¿Por qué la salida de algunos programas de Linux no va a STDOUT ni STDERR?
En realidad, quiero saber cómo capturar de manera confiable todos los resultados del programa, sin importar qué 'transmisión' use. El problema que tengo es que algunos programas no parecen permitir que se capture su salida.
Un ejemplo es el comando 'tiempo':
time sleep 1 2>&1 > /dev/null
real 0m1.003s
user 0m0.000s
sys 0m0.000s
o
time sleep 1 &> /dev/null
real 0m1.003s
user 0m0.000s
sys 0m0.000s
¿Por qué veo la salida en ambas ocasiones? Esperaba que todo se canalizara a / dev / null .
¿Qué flujo de salida usa el tiempo y cómo puedo canalizarlo a un archivo?
Una forma de solucionar el problema es crear un script Bash , por ejemplo, que combine.sh
contenga este comando:
$@ 2>&1
Entonces la salida de 'tiempo' puede capturarse de la manera correcta:
combine.sh time sleep 1 &> /dev/null
(no se ve salida - correcto)
¿Hay alguna manera de lograr lo que quiero sin usar un script de combinación por separado?
2>&1 > /dev/null
significa "2 ahora va a donde va 1 (es decir, el terminal, por defecto), y luego 1 ahora va a / dev / null (¡pero 2 todavía va al terminal!). use>/dev/null 2>&1
para decir "1 va ahora a / dev / null, luego 2 va a donde va 1 (es decir, también a / dev / null). Esto todavía no funcionará aquí ya que el 'tiempo' incorporado no se redirigirá, pero es más correcto en general (por ejemplo, funcionaría si usa / usr / bin / time). Piense en "2> & 1" como copiando la "dirección" de 1 en 2, no como 2 yendo a 1Respuestas:
Esta pregunta se aborda en BashFAQ / 032 . En su ejemplo, usted:
La razón por la cual
no se comporta como espera porque es con esa sintaxis, querrá
time
el comandosleep 1 2>/dev/null
(sí, el comandosleep 1
con stderr redirigido a/dev/null
). La construccióntime
funciona de esa manera para que esto sea realmente posible.La
bash
construcción realmente puede hacer esto porque ... bueno, es una construcción. Tal comportamiento sería imposible con el comando externotime
generalmente ubicado en/usr/bin
. En efecto:Ahora, la respuesta a tu pregunta.
es: lo hace, la salida va a stdout o stderr .
¡Espero que esto ayude!
fuente
exec 3>/some/file ; ls >&3 ;
)coproc
incorporado. Pero no es el caso de latime
construcción.Su pregunta en particular sobre el
time
orden interna ha sido contestada, pero no son algunos comandos que no escriben ya sea astdout
ostderr
. Un ejemplo clásico es el comando Unixcrypt
.crypt
sin argumentos encripta la entrada estándarstdin
y la escribe en la salida estándarstdout
. Solicita al usuario que use una contraseñagetpass()
, que por defecto genera una solicitud/dev/tty
./dev/tty
es el dispositivo terminal actual. Escribir en/dev/tty
tiene el efecto de escribir en el terminal actual (si hay uno, verisatty()
).La razón por la
crypt
que no puede escribirstdout
es porque escribe una salida cifradastdout
. Además, es mejor solicitar en/dev/tty
lugar de escribir parastderr
que, si un usuario redirigestdout
ystderr
, todavía se vea el mensaje. (Por la misma razón,crypt
no se puede leer la contraseñastdin
, ya que se está utilizando para leer los datos para cifrar).fuente
time sleep 1 > /dev/null 2>&1
# redirige la salida "sleep" do null. Luego, "tiempo" escribe su propia salida, sin redireccionamiento. Es como "time (sleep 1 > /dev/null 2>&1)
".(time sleep 1) > /dev/null 2>&1
# ejecuta "time sleep 1", luego redirige su salida a nulo.[] s
fuente
El problema en su caso es que la redirección funciona de otra manera. Tu escribiste
Esto redirige la salida estándar
/dev/null
y luego redirige el error estándar a la salida estándar.Para redirigir todos los resultados, debe escribir
Luego, el error estándar se redirigirá a la salida estándar y, a continuación, se redirigirá toda la salida estándar (que contiene el error estándar)
/dev/null
.fuente
time
. Vea mi respuesta para algunas explicaciones.