Necesito ejecutar varios comandos de shell canalizados desde un script que no sea BASH (es decir, un script PHP) como estos:
command1 | command2 | command3
de modo que, si command1
falla con un código de salida distinto de cero, cada otro comando también falla. Hasta ahora, lo que se me ocurrió es:
set -o pipefail && command1 | command2 | command3
Pero a pesar de que se ejecuta bien desde la terminal, produce esto si se ejecuta desde el script:
sh: 1: conjunto: opción ilegal -o pipefail
linux
command-line
shell
pipe
Desmond Hume
fuente
fuente
/bin/sh
no le gustaset -o pipefail
. ¿Está realmentebash
disfrazado o es un caparazón diferente? Cuandobash
se ejecuta como/bin/sh
, ¿aceptaset -o pipefail
?/bin/sh set -o pipefail
dice/bin/sh: 0: Can't open set
(lo mismo consudo
). Espero haberlo probado bien. El sistema es Ubuntu 12./bin/sh -c "set -o pipefail"
; tal como estaba, el shell intentaba ejecutar un script en el directorio actual llamadoset
y no lo encontró./bin/sh -c "set -o pipefail"
no funciona, sin embargo,bash -c "set -o pipefail"
sí./bin/sh
lo que no reconoceset -o pipefail
. En consecuencia, deberá asegurarse de que el script se ejecute en/bin/bash
lugar de hacerlo/bin/sh
. O, si tiene confianza, valiente, y probablemente insensato, cambie/bin/sh
para ser un enlace o copia de, en/bin/bash
lugar de cualquier shell al que esté vinculado actualmente o una copia. Si está seguro de que/bin/sh
es asíbash
, está utilizando un comportamiento quebash
no se expone cuando se ejecuta como/bin/sh
; usarbash
comobash
.Respuestas:
Desde la línea de comando Bash, debería invocar una subshell para evitar que
pipefail
se establezca después:Esto limitaría el efecto de la
pipefail
opción al subshell creado por los paréntesis(...)
.Un verdadero ejemplo:
Si usa una llamada de shell explícita con la
-c
opción, no necesita una subshell, ya sea conbash
o con unsh
alias parabash
:Como su
sh
no acepta lapipefail
opción, tendría que suponer que se trata de una versión anterior o modificada debash
, o que en realidad es algún otro shell por completo.fuente
$
en la primera pieza una parte del comando, es solo un indicador de shell? Intenté en ambos sentidos, realmente no funcionó. Labash -c
forma siempre funciona, aunque no demasiado elegante ...No estoy seguro de por qué no se mencionó anteriormente, pero es posible desarmar explícitamente
pipefail
, usandoset +o pipefail
.Si está ejecutando un fragmento y no está seguro acerca del
pipefail
conjunto ya configurado, puede usar esto con la subshell como se sugirió anteriormente:fuente
Puede usar $ (comando1) combinado con $? :
Imprime "abc"
Imprime "".
"[$? -eq 0] &&" significa que el siguiente comando se ejecuta solo si el anterior tuvo éxito.
Eso no responde a su pregunta, pero es una solución a su problema.
fuente
command1 && command2 && command3