Подвохи при использовании bash

Что: 0630e96a5148d8f43b8873fc013acac53cb0f677

Когда: 2022-02-16 18:45:38+03:00

Темы: zsh

Подвохи при использовании bash

http://mywiki.wooledge.org/BashPitfalls
Очень хорошая подборка не банальных косяков, которую бы стоило почитать
всем кто пишет что-то на shell. БОльшая часть тут касается и POSIX shell.

Чтобы прочитать список файлов в иерархии, то рекомендуют делать так:

    while IFS= read -r -d '' file; do
        some_command "$file"
    done < <(find . -type f -name '*.mp3' -print0)

Действительно, лучшего способа для POSIX/bash не найти (для POSIX только
нужно будет перенаправить find через pipe). Для zsh можно было бы:

    for file (**.mp3(.)) {
        some_command $file
    }

И обратить внимание на отсутствие кавычек. В zsh это безопасно. Пишут
что в bash 4.0 можно делать так:

    shopt -s globstar
    for file in ./**/*.mp3; do
        some command "$file"
    done

Копировать $file в $target не безопасно, так как $file может иметь
дефисы в начале. И это касается многих других команд. Всякие GNU-шные
понимают "--" аргумент, означающий конец всех опций. Но это зависит от
конкретной программы. Не знал, но как хак применяют добавление "./" к
пути файла.

Отмечен старый хак с [ x"$foo" = xbar ], но и верно замечено что уже
давно в нём смысла нет -- проблемы с дефисом в $foo могли возникнуть
уже в очень старых версиях shell-ов.

Чтобы в ps|grep не попал сам grep, то можно делать: ps ax | grep '[g]edit'
Не слышал прежде про это. Но дальше верно замечают что правильнее и
легче использовать конечно pgrep (хотя я и не знаю насколько его опции
портируемы).

bash не в состоянии будет сделать это: for i in {1..$n}
поэтому советуют делать так: for ((i=1; i<=n; i++)); do ...
В zsh, конечно же, с этим проблем нет: for i ({1..$n})

Сам бы я наверное не догадался что же выведет следующая конструкция
(впрочем про (()) я и так ничего не знаю):

    i=0
    true && ((i++)) || ((i--))
    echo "$i"

Выведет 0, так как код возврата (()) равен выражению внутри и будет
равен 1 ($i тоже будет равен 1), что для shell означает плохой код
возврата и будет выполнено ((i--)), сделав $i равным 0.

оставить комментарий

Сгенерирован: SGBlog 0.34.0