From 0630e96a5148d8f43b8873fc013acac53cb0f677 Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Wed, 16 Feb 2022 18:45:38 +0300 Subject: [PATCH] =?utf8?q?=D0=9F=D0=BE=D0=B4=D0=B2=D0=BE=D1=85=D0=B8=20?= =?utf8?q?=D0=BF=D1=80=D0=B8=20=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7?= =?utf8?q?=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B8=20bash?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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. -- 2.50.0