Как передать аргументы скрипта, содержащие кавычки / пробелы?
Я пытаюсь написать скрипт notify-finish
это может быть добавлено к любой команде. Когда это будет сделано, он запустит команду, заданную приведенными ниже аргументами, а затем отправит пользователю по электронной почте, когда команда будет завершена. Вот что у меня есть:
PROG=
# Run command given by arguments
$@
ECODE=$?
echo -e "Subject: `hostname`: $PROG finishedrnTo: <$USER>rnrnExited with $ECODErn" | sendmail $USER
это работает большую часть времени, но когда аргументы содержат пробелы, кавычки снял.
пример:
notify-finished rsync -avz source/ user@remote:dest/
не например:
notify-finished rsync -avz -e 'ssh -c blowfish' source/ user@remote:dest/
во втором случае $@
расширяется из к rsync -avz -e ssh -c blowfish source user@remote:dest/
, отсутствуют одинарные кавычки. Он не работает ни с двойными кавычками, ни с $*
.
после прочтения других сообщений я попытался поместить команду в массив, но я получаю точно такую же проблему:
CMD=(notify-finished rsync -avz -e 'ssh -c blowfish' source/ user@remote:dest/)
${CMD[@]}
как я могу сделать эту работу для всех аргументов?
3 ответов
использовать "$@"
С цитаты:
prog=""
"$@"
ecode="$?"
echo "$prog exited with $ecode"
это пройдет каждый аргумент точно так, как он был получен. Если вы не включаете кавычки, каждый элемент будет разделен в соответствии с $IFS
:
-
"$@"
как"" "" "" ...
, передавая каждый элемент как отдельный аргумент. -
"$*"
как" ..."
, передавая все элементы, объединенные в один аргумент -
$*
и$@
как...
, нарушая вверх по каждому элементу на пробелах, расширяя все глобусы и передавая каждое результирующее слово как отдельный элемент ($IFS
).
то же самое верно для массивов, таких как "${array[@]}"
и "${array[*]}"
поместите двойные кавычки вокруг подстановок переменных, чтобы они не анализировались (обратите внимание, что это относится ко всем переменным:$@
, и
$PROG
). Также: не ставьте $ перед именем переменной при назначении ему; используйте #
для комментариев; и, в последней строке, одинарные кавычки будут препятствовать замене переменных вообще.
PROG=""
shift
# Run program below
"$PROG" "$@"
ECODE=$? # note: this will always be a number, so it doesn't have to be protected with double-quotes
echo -e "Subject: $(hostname): $PROG finished\r\nTo: <$USER>\r\n\r\nExited with $ECODE\r\n' | sendmail "$USER"
ваш скрипт должен быть таким:
# Run program below
PROG="$@"
${PROG}
ECODE=$?
echo -e "Subject: $(hostname): ${PROG} finished\r\nTo: <$USER>\r\n\r\nExited with $ECODE\r\n"
Final Echo command нуждается в двойных кавычках вместо одинарной кавычки '
для интерпретации и расширения $
переменные.
и вы должны заключать аргумент командной строки в двойные кавычки, а также так:
notify-finished "rsync -avz -e 'ssh -c blowfish' source/ user@remote:dest/"