Pedindo ao Bash para fazer cd em cada diretório sob algum caminho e executar um comando quando ele estiver dentro?

3

Siga este caminho, por exemplo: /var/www/html .

Dentro da pasta html , existem alguns subdiretórios. Eu preciso do sistema para ir em cada um desses subdiretórios via cd (deve ser cd ) e, em seguida, executando um comando quando está dentro deste diretório, volte para / var / www / html e assim repita o processo com o próximo diretório.

Isso é o que eu tentei, mas parece ineficaz:

find /var/www/html/* -type d -maxdepth 0 ! -name 'phpmyadmin' -exec cd * && wp plugin update --all {} \;
    
por JohnDoea 05.04.2017 / 02:20

3 respostas

4

Vamos primeiro desmontar o seu comando:

find /var/www/html/* -type d -name 'phpmyadmin' -maxdepth 0 ! -exec cd * && wp plugin update --all {} \;

O que isso realmente vai fazer é:

  1. O shell vai expandir /var/www/html/* . Vamos supor que se expande para /var/www/html/foo e /var/www/html/bar .
  2. O shell vai expandir * (o seu cd * ). Note que este é o diretório de trabalho atual. Vamos supor que você tenha pop e tart .
  3. O shell executará find /var/www/html/foo /var/www/html/bar -type d -name phpmyadmin -maxdepth 0 ! -exec cd pop tart .
  4. find lançará um erro sobre um comando não finalizado porque viu -exec , mas não ; ou + .

Então, para ficar claro o que está acontecendo, o shell está quebrando a linha, e passando apenas parte do que você queria ser um argumento para find .

A maneira mais clara e simples de fazer isso com find é:

find /var/www/html/* -type d -name phpmyadmin -maxdepth 0 -exec sh -c 'cd "$1" && wp plugin update --all' -- {} \;

Isto cita o comando inteiro, alimenta-o para sh e, em seguida, passa o diretório como um argumento.

Além disso, esse é o gosto pessoal, mas para coisas como essa, eu diria que é mais fácil não usar find :

for dir in /var/www/html/*/; do cd "$dir" && wp plugin update --all; done
    
por 05.04.2017 / 06:31
1

Vamos criar um script de shell tmp.sh desse cd para o seu diretório e fazer o trabalho. Agora cd em um filho não influencia pai, então depois que o script sair, você está de volta no diretório de chamada

#!/bin/sh
cd "$1" 
wp plugin update --all

e depois

 type d -name 'phpmyadmin' -maxdepth 0 ! -exec ./tmp.sh '{}' \;
    
por 05.04.2017 / 05:36
1

Outra maneira seria com um pequeno loop for. Você poderia isso em uma linha com

for folder in */; do <your-commands-on-$folder>; done

Usando seu exemplo que poderia ser

for folder in /var/www/html/*/phpmyadmin/; do cd "$folder"; wp plugin update --all; done
    
por 05.04.2017 / 11:33