Passando um argumento para vários comandos em uma única linha

8

Gostaria de poder executar vários comandos no mesmo arquivo em uma única linha. A maneira que eu atualmente faço isso é:

commandA file && commandB file && perl -ne '...' file

Meu instinto me diz que deve haver uma maneira de fornecer o argumento filename apenas uma vez e enviá-lo para ambos os comandos simultaneamente através de xargs ou algo similar:

find file | xargs commandA && xargs commandB && xargs perl -ne '...'

Quando eu tento isso, apenas o primeiro comando é executado. Como posso conseguir o que quero fazer?

    
por Zaid 30.08.2010 / 10:12

4 respostas

12

Você pode definir uma variável local para isso:

f=file; commandA $f && commandB $f && ...

Você também pode executar tudo incondicionalmente (substituindo && por ; ) ou em paralelo (substituindo && por & ).

Como alternativa, você também pode usar a expansão do histórico do shell para fazer referência a argumentos anteriores:

commandA file && commandB !:1 && ...
    
por 30.08.2010 / 11:05
8

Para shells como Bash, Korn e Z que possuem substituição de processo, você pode fazer isso:

find file | tee >(xargs commandA) >(xargs commandB) >(xargs perl -ne '...')
    
por 30.08.2010 / 23:55
1

Eu não votaria em mim mesmo. É bobo e perigoso, mas apenas no interesse de listar as maneiras de fazer isso, há:

for cmd in "commandA" "commandB" "perl -ne '...'" ; do eval $cmd file ; done

    
por 31.08.2010 / 04:23
1

Você pode usar xargs para construir uma linha de comando, por exemplo:

echo file | xargs -i -- echo ls -l {}\; wc -l {}

Apenas insira o acima no bash para executá-lo:

echo file | xargs -i -- echo ls -l {}\; wc -l {} | bash

Estendendo o exemplo para todos os arquivos * .c no diretório atual (escapando o ls aqui para evitar qualquer substituição de alias do shell):

\ls -1 *.c | xargs -i -- echo ls -l {}\; wc -l {} | bash
    
por 14.01.2011 / 10:20