Я читал о том, что я должен заключать в кавычки переменные в bash, например, «$ foo» вместо $ foo. Однако при написании скрипта я обнаружил случай, когда он работает без кавычек, но не с ними:
wget_options='--mirror --no-host-directories'
local_root="$1" # ./testdir recieved from command line
remote_root="$2" # ftp://XXX recieved from command line
relative_path="$3" # /XXX received from command line
Этот работает:
wget $wget_options --directory_prefix="$local_root" "$remote_root$relative_path"
Этот не делает (обратите внимание на двойные кавычки вокруг $ wget_options):
wget "$wget_options" --directory_prefix="$local_root" "$remote_root$relative_path"
Что является причиной этого?
Является ли первая строка хорошей версией; или я должен подозревать, что где-то есть скрытая ошибка, которая вызывает такое поведение?
В общем, где я могу найти хорошую документацию, чтобы понять, как работает bash и его цитирование? Во время написания этого сценария я чувствую, что начал работать методом проб и ошибок вместо понимания правил.
wget
не знаете, что --mirror --no-host-directories
значит (как один аргумент), но он обрабатывает его, когда он разбит на два аргумента. Очень немногие программы обрабатывают пробелы и кавычки, особенно когда они находятся внутри вектора аргумента. Проблема в том bash
, что и другие оболочки должны быть>
bash
, так что вы можете себе представить, что $a
это точно эквивалентно непосредственному написанию его содержимого. Теперь проблема очевидна: a="-a -b"; cmd "$a"
расширяется cmd "-a -b"
, но, cmd
вероятно, не знает, что это значит. cmd $a
расширяется до cmd -a -b
, что, вероятно , работает.