Я пытаюсь написать скрипт, который будет запускаться в заданном каталоге со многими одноуровневыми подкаталогами. Сценарий перейдет в каждый из подкаталогов, выполнит команду для файлов в каталоге и перейдет в следующий каталог. Каков наилучший способ сделать это?
shell-script
Что-то джонс
источник
источник
youtube-dl
.Ответы:
источник
for d in ./*/
запускает цикл, который хранит каждый элемент в./*/
(список файлов / папок, в данном случае) хранится в переменной$d
.do (cd "$d" && somecommand);
запускает тело цикла. Внутри тела, он начинает подоболочку и бежитcd
иsomecommand
команду. Поскольку это дочерняя оболочка, родительская оболочка (оболочка, из которой вы запускаете эту команду) сохраняет свои CWD и другие переменные среды.done
просто закрывает тело циклаfor d in ./*/ ; do (cd "$d" && ls); done
не будет работать. ноfor d in ./*/ ; do (cd "$d" && for d in ./*/ ; do (cd "$d" && ls); done ); done
будет работать. -использование ls в качестве команды в этом примере.-bash: cd: ./*/: No such file or directory
Лучший способ - вообще не использовать
cd
:execdir
вродеexec
, но рабочий каталог другой:Это не POSIX.
источник
find
выполняет эти команды, поэтому он не будет знать о псевдонимах. Чтоmd
и является.link
каталогом?bash
:find . -type f -iname '*.link' -execdir ${BASH_ALIASES[md]} -i {} \;
Вам не нужно делатьcat
с этимwget
, у которого есть-i
флаг для чтения в URL из файла. Кроме того, это несколько отличается от вашего первоначального вопроса (поскольку вас интересуют только файлы с именами,.link
а не любые другие файлы, которые могут присутствовать).Приведенная выше команда не нуждается в каких-либо подоболочках - она просто отслеживает свой прогресс в текущей оболочке, чередуя
$OLDPWD
и$PWD
. Когда выcd -
обмениваетесь значения этих двух переменных, в основном, как он меняет каталоги. Он также печатает имя для каждого каталога, так как он работает там в stderr.Я только что взглянул на это и решил, что смогу лучше справиться с обработкой ошибок. Он пропустит каталог, в который он не может
cd
- иcd
напечатает сообщение о том, почему stderr - и будетbreak
иметь ненулевой код выхода, если вашcommand
не выполняется успешно или если запускcommand
каким- либо образом влияет на его способность вернуться в исходный каталог -$OLDPWD
. В этом случае он также делаетcd -
последний - и записывает полученное имя текущего рабочего каталога в stderr.источник
источник