web-development-kb-pt.site

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

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

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

Meu instinto do intestino me diz que deve haver uma maneira de fornecer o argumento de nome de arquivo apenas uma vez e pipe para ambos os comandos simultaneamente através de xargs ou algo similar:

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

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

10
Zaid

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

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

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

Como alternativa, você também pode usar a expansão do Histórico de Shell para referência a argumentos anteriores:

commandA file && commandB !:1 && ...
12
maxschlepzig

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

find file | tee >(xargs commandA) >(xargs commandB) >(xargs Perl -ne '...')
8

Você pode usar o Xargs para construir uma linha de comando e.:

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

Apenas tube o acima em bash para executá-lo:

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

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

\ls -1 *.c | xargs -i -- echo ls -l {}\; wc -l {} | bash
2
frielp

Eu não votaria para isso sozinho. É 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

1
frabjous