Estou tentando escrever um script que será executado em um determinado diretório com muitos subdiretórios de nível único. O script cdará em cada um dos subdiretórios, executará um comando nos arquivos no diretório e sairá para continuar no próximo diretório. Qual é a melhor maneira de fazer isso?
shell-script
Algo Jones
fonte
fonte
youtube-dl
.Respostas:
fonte
for d in ./*/
inicia um loop que armazena todos os itens./*/
(uma lista de arquivos / pastas, neste caso) em uma variável$d
.do (cd "$d" && somecommand);
inicia o corpo do loop. Dentro do corpo, ele inicia um subshell e executa os comandoscd
esomecommand
. Como é um shell filho, o shell pai (o shell do qual você está executando este comando) mantém seu CWD e outras variáveis de ambiente.done
simplesmente fecha o corpo do loop.for d in ./*/ ; do (cd "$d" && ls); done
não funcionará. masfor d in ./*/ ; do (cd "$d" && for d in ./*/ ; do (cd "$d" && ls); done ); done
vai funcionar. -Usando ls como o comando neste exemplo.-bash: cd: ./*/: No such file or directory
A melhor maneira é não usar
cd
:execdir
é comoexec
, mas o diretório de trabalho é diferente:Não é POSIX.
fonte
find
executa esses comandos, para que não tenha conhecimento de aliases. O que émd
e é o.link
diretório a?bash
:find . -type f -iname '*.link' -execdir ${BASH_ALIASES[md]} -i {} \;
Você não precisa fazercat
comwget
que tem uma-i
bandeira para a leitura em uma URL de um arquivo. Além disso, isso é um pouco diferente da sua pergunta original (já que você parece estar interessado apenas nos arquivos nomeados.link
e não em outros arquivos que possam estar presentes).O comando acima não precisa fazer nenhum subshells - apenas rastreia seu progresso no shell atual alternando
$OLDPWD
e$PWD
. Quandocd -
o shell troca o valor dessas duas variáveis, basicamente, à medida que altera os diretórios. Ele também imprime o nome de cada diretório, pois trabalha lá para stderr.Acabei de dar uma segunda olhada e decidi que poderia fazer um trabalho melhor com o tratamento de erros. Irá pular um diretório no qual não pode
cd
- ecd
imprimirá uma mensagem sobre o motivo de stderr - e exibirábreak
um código de saída diferente de zero se o seucommand
não for executado com êxito ou se a execuçãocommand
afetar de alguma forma a capacidade de retornar ao diretório original -$OLDPWD
. Nesse caso, ele também faz umacd -
última - e grava o nome do diretório de trabalho atual resultante no stderr.fonte
fonte