В bash можно избежать аргументов, содержащих пробелы.
foo "a string"
Это также работает для аргументов команды или функции:
bar() {
foo "$@"
}
bar "a string"
Пока все хорошо, но что, если я хочу манипулировать аргументами перед вызовом foo?
Это не работает:
bar() {
for arg in "$@"
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
Итак, как вы составляете списки аргументов, если аргументы содержат пробелы?





Используйте массивы (один из скрытые особенности в Bash).
Кажется, не существует простого способа передать массивы функциям (которые на самом деле являются подоболочками). Вам нужно будет заключить их в кавычки и передать в качестве обычного аргумента (как и любой другой команде).
Есть (как минимум) два способа сделать это:
Используйте массив и расширьте его с помощью "${array[@]}":
bar() {
local i=0 args=()
for arg in "$@"
do
args[$i] = "prefix $arg"
((++i))
done
foo "${args[@]}"
}
Итак, что мы узнали? "${array[@]}" относится к ${array[*]}, как "$@" для $*.
Или, если вы не хотите использовать массивы, вам нужно использовать eval:
bar() {
local args=()
for arg in "$@"
do
args = "$args \"prefix $arg\""
done
eval foo $args
}
блин, надо было раньше приехать - мог бы избавить тебя от работы :)
Вы можете использовать массивы так, как вы предлагаете, с небольшими изменениями. Строка, вызывающая foo, должна читать
foo "${args[@]}"
У меня тоже была проблема с этим. Я писал сценарий bash для резервного копирования важных файлов на моем компьютере с 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
Вот более короткая версия, не требующая использования числового индекса:
(пример: создание аргументов для команды find)
dir=$1
shift
for f in "$@" ; do
args+=(-iname "*$f*")
done
find "$dir" "${args[@]}"
shift так не работает в Bash. Вместо этого должен быть dir=$1; shift.
Действительно, исправил.
как именно? Я обновил свой вопрос, пытаясь использовать массив, но это не сработало.