我正在破折号中编写符合POSIX标准的脚本,因此我必须使用虚假阵列发挥创意。
fake_array.sh的内容
fake_array_job() {
array="$1"
job_name="$2"
comma_count="$(echo "$array" | grep -o -F ',' | wc -l)"
if [ "$comma_count" -lt '1' ]; then
echo 'You gave a fake array to fake_array_job that does not contain at least one comma. Exiting...'
exit
fi
array_count="$(( comma_count + 1 ))"
position=1
while [ "$position" -le "$array_count" ]; do
item="$(echo "$array" | cut -d ',' -f "$position")"
"$job_name" || exit
position="$(( position + 1 ))"
done
}
script.sh的内容
#!/bin/sh
. fake_array.sh
job_to_do() {
echo "$item"
}
fake_array_job 'goat,pig,sheep' 'job_to_do'
second_job() {
echo "$item"
}
fake_array_job 'apple,orange' 'second_job'
我知道为我传递给fake_array_job的每个作业使用一个唯一的名称似乎很愚蠢,但我喜欢我必须输入两次因为它有助于减少人为错误。
我一直在读,将变量用作命令是个坏主意。我使用" $ job_name"运行功能有任何负面影响,因为它涉及稳定性,安全性或效率?
答案 0 :(得分:1)
(阅读最后查看Charles Duffy提出的一个好建议。我太懒了,不能完全改写我之前提到它的答案......)
你可以迭代"数组"使用简单的参数扩展而不需要数组中的多个元素。
fake_array_job() {
args=${1%,}, # Ensure the array ends with a comma
job_name=$2
while [ -n "$args" ]; do
item=${args%%,*}
"$job_name" || exit
args=${args#*,}
done
}
上面的一个问题是通过假设foo,bar,
不是带有空的最后一个元素的逗号分隔数组来确保数组以逗号结尾。一个更好(虽然更丑陋)的解决方案是使用read
来分解数组。
fake_array_job () {
args=$1
job_name=$2
rest=$args
while [ -n "$rest" ]; do
IFS=, read -r item rest <<EOF
$rest
EOF
"$job_name" || exit
done
}
(您可以使用<<-EOF
并确保此处的文档是使用标签缩进的,但在此处很难传达,所以我只是离开丑陋的版本。)
还有Charles Duffy建议使用case
对数组进行模式匹配,以确定是否还有逗号:
while [ -n "$args" ]; do
case $var in
*,*) next=${args%%,*}; var=${args#*,}; "$cmd" "$next";;
*) "$cmd" "$var"; break;;
esac;
done