bash centos xargs

bash xargs



Ignorar resultado vacĂ­o para xargs (5)

Considera este comando:

ls /mydir/*.txt | xargs chown root

La intención es cambiar los propietarios de todos los archivos de texto en mydir para mydir

El problema es que si no hay archivos .txt en mydir , xargs genera un error que indica que no hay una ruta especificada. Este es un ejemplo inofensivo porque se lanza un error, pero en algunos casos, como en el script que necesito usar aquí, se supone que una ruta en blanco es el directorio actual. Entonces, si ejecuto ese comando desde /home/tom/ luego, si no hay ningún resultado para ls /mydir/*.txt y todos los archivos en /home/tom/ tienen sus propietarios cambiados a raíz.

Entonces, ¿cómo puedo hacer que xargs ignore un resultado vacío?


En OSX: Bash reimplementation de xargs tratan con el argumento -r , pon eso, por ejemplo, en $HOME/bin y agrégalo a la PATH :

#!/bin/bash stdin=$(cat <&0) if [[ $1 == "-r" ]] || [[ $1 == "--no-run-if-empty" ]] then # shift the arguments to get rid of the "-r" that is not valid on OSX shift # wc -l return some whitespaces, let''s get rid of them with tr linecount=$(echo $stdin | grep -v "^$" | wc -l | tr -d ''[:space:]'') if [ "x$linecount" = "x0" ] then exit 0 fi fi # grep returns an error code for no matching lines, so only activate error checks from here set -e set -o pipefail echo $stdin | /usr/bin/xargs $@


En términos de xargs , puede usar -r como se sugiere, sin embargo, no es compatible con BSD xargs .

Así que, como solución, puede pasar algún archivo temporal adicional, por ejemplo:

find /mydir -type f -name "*.txt" -print0 | xargs -0 chown root $(mktemp)

o redirigir su stderr a nulo ( 2> /dev/null ), por ejemplo

find /mydir -type f -name "*.txt" -print0 | xargs -0 chown root 2> /dev/null || true

Otro enfoque mejor es iterar sobre los archivos encontrados usando while loop:

find /mydir -type f -name "*.txt" -print0 | while IFS= read -r -d '''' file; do chown -v root "$file" done

Consulte también: Ignorar resultados vacíos para xargs en Mac OS X

También tenga en cuenta que su método para cambiar los permisos no es bueno y está desaconsejado. Definitivamente, no debería analizar la salida del comando ls (consulte: mywiki.wooledge.org/ParsingLs ). Especialmente cuando ejecuta su comando por root, porque sus archivos pueden consistir en caracteres especiales que pueden ser interpretados por el intérprete de comandos o imaginar que el archivo tiene un carácter de espacio alrededor de / , los resultados pueden ser terribles.

Por lo tanto, debe cambiar su enfoque y usar el comando find lugar, por ejemplo

find /mydir -type f -name "*.txt" -execdir chown root {} '';''


Los usuarios de -L <#lines> no sean de GNU pueden aprovechar -L <#lines> , -n <#args> , -i , y -I <string> :

ls /empty_dir/ | xargs -n10 chown root # chown executed every 10 args or fewer ls /empty_dir/ | xargs -L10 chown root # chown executed every 10 lines or fewer ls /empty_dir/ | xargs -i cp {} {}.bak # every {} is replaced with the args from one input line ls /empty_dir/ | xargs -I ARG cp ARG ARG.bak # like -i, with a user-specified placeholder

Tenga en cuenta que xargs divide la línea en el espacio en blanco, pero están disponibles las citas y los escapes; RTFM para más detalles.


Para GNU xargs , puede usar la --no-run-if-empty -r o --no-run-if-empty :

--no-run-if-empty
-r
Si la entrada estándar no contiene ningún nonblanks, no ejecute el comando. Normalmente, el comando se ejecuta una vez, incluso si no hay entrada. Esta opción es una extensión de GNU.


man xargs dice --no-run-if-empty .