Eu tenho dois problemas. Estou tentando passar arquivos por um canal como argumento e estou tentando usar esse arquivo como uma variável dentro da sh
função.
Aqui está o meu comando:
find . -name 'segment*' | xargs -n1 -P4 sh someFunction.sh
Aqui, minha linha está encontrando todos os arquivos que se parecem com " segment.something
" e passando-os para o lado direito do pipe. Em someFunction.sh
, preciso do nome do arquivo como argumento. Digamos que o arquivo que está sendo inserido em segment1
.
O someFunction.sh
irá imprimir cada linha de segment1
(por exemplo).
Como passo a saída do lado esquerdo do tubo para o lado direito e como faço para chamá-la dentro someFunction.sh
?
Responder1
Seu comando
$ find . -name 'segment*' | xargs -n1 -P4 sh someFunction.sh
tem o efeito de que no máximo quatro cópias do someFunction.sh
shell script serão iniciadas ( -P 4
) em paralelo (novas serão geradas assim que as antigas forem concluídas), cada uma recebendo um nome de arquivo como argumento ( -n 1
).
Isso significa que cada invocação do seu script será semelhante a
sh someFunction.sh segmentsomething
Dentro do script, o shell colocará os valores doparâmetros posicionais(os argumentos na linha de comando) into $1
, $2
etc. ( $0
geralmente contém o nome do próprio script). No seu caso, $1
conterá o nome do arquivo e os demais ficarão vazios.
Então, no roteiro:
filename="$1"
echo "$filename"
cat "$filename"
É isso. Agora, normalmente, quando alguém procura find
arquivos e passa seus nomes de arquivos, xargs
há o problema com nomes de arquivos instáveis dos quais as pessoas tendem a lembrar umas às outras, e farei isso aqui também.
O find
utilitário passa nomes de arquivos separados por espaços em branco. Isso não é bom se você tiver nomes de arquivos com espaços, pois isso causaria problemas para xargs
invocar seu script com nomes próprios.
Portanto, é uma boa práticasempreuse -print0
with find
e -0
with xargs
, o que significa que os nomes dos arquivos, em vez de serem separados por espaços, são separados por nul
caracteres ( \0
). Isso torna muito mais seguro.
Por isso:
$ find . -name 'segment*' -print0 | xargs -0 -n1 -P4 sh someFunction.sh
Responder2
Você poderia usar algo assim, assumindo someFunction.sh
que esteja em seu diretório de trabalho.
find . -name 'segment*' -print0| xargs -0 -n1 -P4 ./someFunction.sh
O -print0
e -0
permite arquivos com espaços no nome (um problema comum). No meu someFunction.sh
eu tenho
#!/bin/bash
echo "Arg: " $1
cat $1
Que simplesmente ecoa o nome do arquivo e grava o conteúdo do arquivo passado parasomeFunction.sh