Las llaves solo agrupan los comandos, de modo que el signo de tubería |afecta a la salida combinada.
También puede usar paréntesis ()alrededor de un grupo de comandos, que ejecutaría los comandos en una subshell. Esto tiene un conjunto sutil de diferencias con llaves, por ejemplo, intente lo siguiente:
cd $HOME/Desktop ; (cd $HOME ; pwd) ; pwd
cd $HOME/Desktop ; { cd $HOME ; pwd ; } ; pwd
Verá que todas las variables de entorno, incluido el directorio de trabajo actual, se restablecen después de salir del grupo de paréntesis, pero no después de salir del grupo de llaves.
En cuanto al punto y coma, las alternativas incluyen los signos &&y ||, que ejecutarán condicionalmente el segundo comando solo si el primero es exitoso o no, respectivamente, p. Ej.
cd $HOME/project && make
ls $HOME/project || echo "Directory not found."
Eso funciona! Ayúdame a aprender: ¿qué están haciendo exactamente las llaves aquí? ¿Qué otros poderes mágicos tienen?
David Oneill
@DavidOneill { list; }es un comando compuesto . From bash(1): list simplemente se ejecuta en el entorno actual de shell. La lista debe terminarse con una nueva línea o punto y coma. [..] El estado de retorno es el estado de salida de la lista.
Lekensteyn
He agregado un poco más de información a la respuesta. La guía definitiva para las secuencias de comandos de shell con bash es la página de manual de bash, escriba man bashdesde la línea de comandos y navegue por ella.
pablomme
si el ; en esos comandos no se && en caso de que el archivo wordlist.txt no exista?
Rinzwind,
Si wordlist.txtno existe cat, aparecerá un error en el error estándar, pero no en la salida estándar, por wc -llo que no contará ninguna línea desde él. Lo mismo vale para ~/folderno existir. Se podría agregar 2> /dev/nullentre cada uno de estos comandos y su punto y coma para evitar el ruido en el error estándar, pero aparte de ser feo, los mensajes de error son inofensivos con el fin de contar líneas.
pablomme
8
Como wcacepta una ruta de archivo como entrada, también puede usar la sustitución de procesos:
Tenga en cuenta que ls ~/folder/*también devuelve el contenido de los subdirectorios si los hay (debido a la expansión global). Si solo desea enumerar el contenido de ~/folder, simplemente use ls ~/folder.
El wc -lera sólo una compuesta por ejemplo, estoy realmente tuberías en algo más complicado que no tiene esta opción.
David Oneill
2
@DavidOneill Bueno, como catacepta un argumento de archivo, puede usar cat <(cat wordlist.txt; ls wordlist.txt) | wc -le incluso cat wordlist.txt <(ls wordlist.txt) | wc -l. Por supuesto, esto es muy feo, pero demuestra las infinitas posibilidades con las herramientas de línea de comandos.
Lekensteyn
1
@DavidOneill Correcto, lo he corregido ahora, gracias.
Lekensteyn
1
Desea ls ~/folder/que si ~/folderes un enlace simbólico lsenumere el contenido de su destino en lugar del enlace en sí. Por cierto, todos los lscomandos deben seguirse -1para que se imprima un solo archivo por línea y wc -lsea una forma válida de contar archivos.
pablomme
@pablomme Eres sincero sobre el enlace simbólico, pero -1está implícito ya que la salida no es una terminal sino una tubería.
Lekensteyn
2
Me hacía la misma pregunta y terminé escribiendo un guión corto.
magicalUnionThing(Lo llamo append):
#!/bin/sh
cat /dev/stdin
$*
Hacer ese script ejecutable
chmod +x ./magicalUnionThing
Ahora hazlo tú
cat wordlist.txt |./magicalUnionThing ls ~/folder/* | wc -l
Que hace:
Enviar entrada estándar a salida estándar
Ejecutar argumento. $*devuelve todos los argumentos como una cadena. La salida de ese comando va a la salida estándar de script de forma predeterminada.
Entonces, el stdout de magicalUnionThing será su stdin + stdout del comando que se pasa como argumento.
Por supuesto, hay formas más simples, según otras respuestas.
Quizás esta alternativa puede ser útil en algunos casos.
{ list; }
es un comando compuesto . Frombash(1)
: list simplemente se ejecuta en el entorno actual de shell. La lista debe terminarse con una nueva línea o punto y coma. [..] El estado de retorno es el estado de salida de la lista.man bash
desde la línea de comandos y navegue por ella.wordlist.txt
no existecat
, aparecerá un error en el error estándar, pero no en la salida estándar, porwc -l
lo que no contará ninguna línea desde él. Lo mismo vale para~/folder
no existir. Se podría agregar2> /dev/null
entre cada uno de estos comandos y su punto y coma para evitar el ruido en el error estándar, pero aparte de ser feo, los mensajes de error son inofensivos con el fin de contar líneas.Como
wc
acepta una ruta de archivo como entrada, también puede usar la sustitución de procesos:Esto equivale aproximadamente a:
Tenga en cuenta que
ls ~/folder/*
también devuelve el contenido de los subdirectorios si los hay (debido a la expansión global). Si solo desea enumerar el contenido de~/folder
, simplemente usels ~/folder
.fuente
wc -l
era sólo una compuesta por ejemplo, estoy realmente tuberías en algo más complicado que no tiene esta opción.cat
acepta un argumento de archivo, puede usarcat <(cat wordlist.txt; ls wordlist.txt) | wc -l
e inclusocat wordlist.txt <(ls wordlist.txt) | wc -l
. Por supuesto, esto es muy feo, pero demuestra las infinitas posibilidades con las herramientas de línea de comandos.ls ~/folder/
que si~/folder
es un enlace simbólicols
enumere el contenido de su destino en lugar del enlace en sí. Por cierto, todos losls
comandos deben seguirse-1
para que se imprima un solo archivo por línea ywc -l
sea una forma válida de contar archivos.-1
está implícito ya que la salida no es una terminal sino una tubería.Me hacía la misma pregunta y terminé escribiendo un guión corto.
magicalUnionThing
(Lo llamoappend
):Hacer ese script ejecutable
Ahora hazlo tú
Que hace:
$*
devuelve todos los argumentos como una cadena. La salida de ese comando va a la salida estándar de script de forma predeterminada.Entonces, el stdout de magicalUnionThing será su stdin + stdout del comando que se pasa como argumento.
Por supuesto, hay formas más simples, según otras respuestas.
Quizás esta alternativa puede ser útil en algunos casos.
fuente