Comments 39
Спасибо за перевод,
Придётся закавычивать каждый аргумент и экранировать любые символы, необходимые для выхода из этих кавычек…
Как использовать этот трюк для безопасного выполнения команд по ssh? Это невозможно!
Как вариант можно использовать base64
и передавать уже закодированную строку для выполнения. А на другом конце просто делать:
echo "$CMD" | base64 -d | bash
В случае с bash можно также обойтись простой передачей необходимого через пайп.
Еще хотелось бы добавить про экранирование Here Document, например все знают, что эта команда:
CITY=Moscow
cat <<EOT
I live in $CITY
EOT
вернет:
I live in Moscow
Это может быть удобно для подстановки переменных в Here Document.
При необходимости знак "$
" и скобки можно экранировать с помощью "\
"
Но мало кто знает, что можно заэкранировать весь Here Document целиком, например:
BBB=asd
cat <<\EOT
I live in $CITY
EOT
не станет расскрывать переменные и вернет:
I live in $CITY
Это может быть полезным для выполнения скриптов на удаленной машине, например.
Перевел Google's Shell Style Guide, там как раз этот вопрос затрагивается.
Для bash есть какие-нибудь дебаггеры?
Как язык для написания больших программ и утилит bash просто ужасен:
Неудобное и не очевидное управление переменными и их типами;
Отсутствие понятие зон видимости переменных — в результате в большом скрипте сложно их отслеживать;
Сложно парсить вывод утилит и файлов — приходится применять всякие сторонние awk и sed, с тем ещё синтаксисом;
Отсутствие возможности работы с каким либо сторонним API, bash биндингов ожидаемо не существует;
Ну и банально — катастрофически медленное выполнение циклов и условий — по сравнением с bash даже python кажется спринтером.
п.с:
Потому считаю что bash очень хорош, но в своей нише использования. Остальное от лукавого :)
Bash это классный и выразительный язык, если уметь на нем писать. Там есть локальные переменные, функции и много всего остального. В качестве примера рекомендую исходники git или подсистемы конфигурации в openwrt.
О безопасном программировании на bash есть хорошая страница в wiki mywiki.wooledge.org/BashPitfalls
Половина git написана на bash.
Как безопасно программировать в bash.
Программируйте в нормальных языках программирования, а шелл оставьте для ad-hoc однострочников
Никак.
"$var1"«more string content»"$var2"
И куда катится мир? :)
но что хорошего в совместимости
Совместимость это очень хорошо, но не всегда это нужно.
Незакавыченная переменная должна расцениваться как взведённая бомба: она взрывается при контакте с пробелом. Да, «взрывается» в смысле разделения строки на массив.Видите ли, такое поведение достаточно часто требуется. Например:
arguments="xvzf archive.tgz -C /home/user" tar $argumentsС кавычками это будет работать неправильно, т.к. команда должна получить командную строку, порезанную на аргументы функции main().
arcfile="archive.tgz"
current_dir="/home/user"
tar xzvf "$arcfile" "$current_dir"
Скажем так, ваш случай выглядит не так чтобы вынужденно-обязательным. При этом, если часто надо такое писать — можно и функции завести с нужным шаблоном аргументов…
Рекомендую глянуть в файл /etc/rc.conf во FreeBSD — там параметры работы системы задаются в виде аргументов командной строки (ну и есть параметры, указывающие, нужно ли вообще запускать эту команду — например, команду запуска демона, аргументы к которой заданы во второй переменной).
Вот только если имя пользователя или архива содержит пробел — такой способ уже не сработает.
Вот такой способ выглядит более общим:
arguments=(xvzf "архив с пробелом.tgz" -C /home/user)
tar ${arguments[*]}
Однажды мне понадобилось выполнить некий набор команд на удаленной машине. Чтобы не мучиться с кавычками сделал так:
some-function() {
: # do something useful
}
{
declare -f some-function
echo "some-function some-parameters"
} | ssh some-host bash
Как безопасно программировать в bash