Considere este comando:
ls /mydir/*.txt | xargs chown root
A intenção é alterar os proprietários de todos os arquivos de texto mydir
para root
O problema é que, se não houver .txt
arquivos mydir
, o xargs lança um erro dizendo que não há um caminho especificado. Este é um exemplo inofensivo porque um erro está sendo gerado, mas em alguns casos, como no script que eu preciso usar aqui, é assumido que um caminho em branco é o diretório atual. Portanto, se eu executar esse comando a partir de /home/tom/
então, se não houver resultado para ls /mydir/*.txt
e todos os arquivos abaixo /home/tom/
tiverem seus proprietários alterados para raiz.
Então, como posso xargs ignorar um resultado vazio?
ls
para uso programático; consulte mywiki.wooledge.org/ParsingLsgit branch --merged | grep -v '^* ' | xargs git branch -d
que também falha na entrada vaziaRespostas:
Para o GNU
xargs
, você pode usar a opção-r
ou--no-run-if-empty
:fonte
brew install findutils
.findutils
nãofileutils
.Usuários de xargs não-GNU pode tirar proveito de
-L <#lines>
,-n <#args>
,-i
, e-I <string>
:Lembre-se de que o xargs divide a linha no espaço em branco, mas citações e escape estão disponíveis; RTFM para detalhes.
Além disso, como menciona Doron Behar, essa solução alternativa não é portátil, portanto, podem ser necessárias verificações:
fonte
xargs
não suportar o--no-run-if-empty
switch e tentar executar o argumento de comando sem a entrada STDIN (é o caso do Solaris 10). As versões em outros unixes podem simplesmente ignorar uma lista vazia (por exemplo, AIX).echo '' | xargs -n1 echo blah
não faz nada; enquantoecho 'x' | xargs -n1 echo blah
imprime "blá".ls /mydir/*.txt | xargs -n 1 -I {} chown root {}
como esta resposta sugere.echo '' | xargs -n1 echo blah
imprimeblah
com GNUxargs
.man xargs
diz--no-run-if-empty
.fonte
Em termos de
xargs
, você pode usar-r
como sugerido, no entanto, não é suportado pelo BSDxargs
.Portanto, como solução alternativa, você pode passar algum arquivo temporário extra, por exemplo:
ou redirecione seu stderr para null (
2> /dev/null
), por exemploOutra abordagem melhor é iterar sobre os arquivos encontrados usando o
while
loop:Consulte também: Ignorar resultados vazios para xargs no Mac OS X
Observe também que seu método de alterar as permissões não é ótimo e é desencorajado. Definitivamente você não deve analisar a saída do
ls
comando (consulte: Por que você não deve analisar a saída de ls ). Especialmente quando você está executando seu comando pela raiz, porque seus arquivos podem conter caracteres especiais que podem ser interpretados pelo shell ou imaginar o arquivo com um caractere de espaço ao redor/
, os resultados podem ser terríveis.Portanto, você deve alterar sua abordagem e usar o
find
comando, por exemplo,fonte
while IFS= read -r -d '' file
é válido. Você pode explicar?No OSX: Reimplementação Bash de como
xargs
lidar com o-r
argumento, insira isso, por exemplo,$HOME/bin
e adicione-o aoPATH
:fonte
Este é um comportamento do GNU xargs que pode ser suprimido usando -r, --no-run-if-empty.
A variante * BSD do xargs tem esse comportamento no padrão, portanto -r não é necessário. Desde o FreeBSD 7.1 (lançado em janeiro de 2009), um argumento -r é aceito (o que não faz nada) por razões de compatibilidade.
Pessoalmente, prefiro usar longopts em scripts, mas como o * BSD xargs não usa longopts, basta usar "-r" e o xargs agirá da mesma maneira nos sistemas * BSD e linux
O xargs no MacOS (atualmente o MacOS Mojave) infelizmente não suporta o argumento "-r".
fonte