Создавать списки аргументов, содержащие пробелы
В bash можно избежать аргументов, содержащих пробелы.
foo "a string"
Это также работает для аргументов команды или функции:
bar() {
foo "[email protected]"
}
bar "a string"
До сих пор так хорошо, но что, если я хочу манипулировать аргументами до вызова foo
?
Это не работает:
bar() {
for arg in "[email protected]"
do
args="$args \"prefix $arg\""
done
# Everything looks good ...
echo $args
# ... but it isn't.
foo $args
# foo "$args" would just be silly
}
bar a b c
Итак, как вы создаете списки аргументов, когда аргументы содержат пробелы?
Ответы
Ответ 1
Есть (по крайней мере) два способа сделать это:
(1.) Используйте массив и разворачивайте его с помощью "${array[@]}"
:
bar() {
local i=0 args=()
for arg in "[email protected]"
do
args[$i]="prefix $arg"
((++i))
done
foo "${args[@]}"
}
Итак, что мы узнали? "${array[@]}"
до ${array[*]}
, что "[email protected]"
до $*
.
(2). Если вы не хотите использовать массивы, вам нужно использовать eval
:
bar() {
local args=()
for arg in "[email protected]"
do
args="$args \"prefix $arg\""
done
eval foo $args
}
Ответ 2
Вот более короткая версия: (пример построения аргументов для команды find
)
dir=$(shift)
for f in "[email protected]" ; do
args+=(-iname "*$f*")
done
find "$dir" "${args[@]}"
Ответ 3
Используйте arrays (одна из скрытых функций в Bash).
Ответ 4
Вы можете использовать массивы так же, как вы предлагаете, с небольшой детализацией. Строка, вызывающая foo, должна читать
foo "${args[@]}"
Ответ 5
У меня тоже была проблема с этим. Я писал bash script для резервного копирования важных файлов на моем компьютере Windows (cygwin). Я тоже пробовал использовать массив, и у меня все еще были проблемы. Не уверен точно, как я его исправил, но вот части моего кода, которые важны в случае, если это поможет вам.
WORK="d:\Work Documents\*"
# prompt and 7zip each file
for x in $SVN $WEB1 $WEB2 "$WORK" $GRAPHICS $W_SQL
do
echo "Add $x to archive? (y/n)"
read DO
if [ "$DO" == "y" ]; then
echo "compressing $x"
7zip a $W_OUTPUT "$x"
fi
echo ""
done