Execute um determinado comando em cada subpath de um caminho longo

4

Digamos que eu tenha um longo caminho, como:

/a/b/c/d/e/f

Gostaria de executar um comando somente em cada um dos subcaminhos do caminho:

por exemplo. Se o meu comando for cmd , estou procurando por um one-liner que possa ser feito (talvez usando um loop de uma linha)

cmd /a
cmd /a/b
cmd /a/b/c
cmd /a/b/c/d
cmd /a/b/c/d/e
cmd /a/b/c/d/e/f

Uma das razões pelas quais eu preciso disso (eu preciso disso para outras coisas também), é porque eu gostaria de dar a alguém do meu grupo unix a capacidade de cd incrementalmente seu caminho codificar%. Para fazer isso, acho que preciso executar /a/b/c/d/e/f em cada um desses subcaminhos (não tenho certeza se existe uma alternativa). Note que eu quero evitar chmod g+x .

Eu trabalho principalmente no zsh, então gostaria de saber se há algo que aproveite recursos zsh específicos.

    
por Amelio Vazquez-Reina 20.04.2012 / 21:56

4 respostas

3

Adicione isso ao seu arquivo de configuração zsh :

function pathargs {
  local P=$1; local L=${#P}; shift
  local N=1; while [[ $N -le $L ]]; do
    [[ ($N == 1 && ${P[1]} = '/') || \
       ${P[$N]} != '/' && ($N == $L || ${P[$N+1]} == '/') ]] \
    && $@ ${P:0:$N}
    N=$(($N+1))
  done
}

Exemplo:

% pathargs /abc/def/ghi/jkl echo
/
/abc
/abc/def
/abc/def/ghi
/abc/def/ghi/jkl

Você pode usá-lo com chmod -R g+x em vez de echo . O comando será chamado nos diretórios mais altos primeiro.

    
por 20.04.2012 / 22:28
4

Algo como

path=/a/b/c/d/e/f
while test "$path" != "/"; do
    chmod g+x "$path"
    path=$(dirname "$path")
done
    
por 20.04.2012 / 22:29
4

Rápido para digitar e funciona em todos os shells:

(while [ "$PWD" != / ]; do cmd .; cd ..; done)

Os parênteses mantêm a mudança de diretório local. Como o seu exemplo, o diretório raiz é omitido. Se você quiser parar se a execução de cmd falhar, adicione set -e; após o parêntese de abertura.

    
por 22.04.2012 / 02:29
0

Que tal find start_directory -type d -exec my_cmd {} \;

  • start_directory é /a no seu exemplo
  • type d indica apenas diretórios. type f para arquivos. Deixe esse argumento para arquivos e diretórios.
  • my_cmd é cmd no seu exemplo
  • {} é substituído pelo nome do diretório encontrado
  • \; não se esqueça, o comando não funcionará sem ele.

Exemplo1 : Isso imprimirá todos os nomes de diretório de caminho completo em / home:

find /home -type d -exec echo {} \;

Example2 : este é o seu caso de uso:

find /a -type d -exec echo chmod g+x {} \;

Imprime os comandos, não os executa. Você pode verificar se é realmente o que você quer e, em caso afirmativo, você pode canalizá-lo para bash (ou zsh, se desejar):

find /a -type d -exec echo chmod g+x {} \; | bash
    
por 20.04.2012 / 22:03