Cómo ejecutar un comando en segundo plano sin salida a menos que haya un error

14

¿Cómo suprimir la salida de un comando pero mostrarlo si la salida del comando codifica un error?

Xster
fuente

Respuestas:

17

Desafortunadamente, la suposición que stderrsolo se usa para la salida de error no siempre es correcta. Por el contrario, a stderrmenudo se usa para todos y cada uno de los resultados y diagnósticos interactivos , es decir, los resultados destinados al usuario a leer en un mensaje interactivo 1 . wgety ddson ejemplos bien conocidos.

Algunos comandos proporcionarán un indicador (por ejemplo, -quietor -silent) para suprimir la salida sin error; lea sus páginas de manual para ver si existe.


Otra convención que es más frecuente es el código de salida : un programa devuelve un código de salida cuando sale. Típicamente 2 , un código de salida de 0indica éxito, y cualquier otro código de salida indica un error.

Con bash, puede obtener el código de salida del último comando de la $?variable. En fish, use la $statusvariable. Puede canalizar stderra un archivo temporal y solo imprimirlo si se produce un error. Por ejemplo ( fish):

command 2>/tmp/outputbuffer
if $status
    cat /tmp/outputbuffer
rm /tmp/outputbuffer

También puede usar algunos atajos, si no está encadenando comandos:

if command 2>/tmp/outputbuffer
    cat /tmp/outputbuffer
rm /tmp/outputbuffer

O:

command 2>/tmp/outputbuffer; or cat /tmp/outputbuffer; rm /tmp/outputbuffer;

También puede canalizar stdoutal mismo búfer utilizando 2>&1 >/tmp/outputbuffer.

(Nota: en realidad no lo sé fish, así que estoy adaptando el concepto a lo que puedo encontrar en su documentación. La sintaxis puede ser ligeramente incorrecta. Además, puede usarla mktemppara generar un archivo temporal único: ejecútelo y grabe el nombre de archivo en una variable.)

Si necesita ejecutar todo en el fondo de un shell que también está utilizando de forma interactiva al mismo tiempo, entonces es mejor escribir un script para manejar la salida oculta y ejecutar ese script en segundo plano con las técnicas estándar ( fish) Heck, puedes poner algo como la siguiente función en ~/.config/fish/config.fish:

function run-silent
    set temp (mktemp)
    if $argv 2>&1 >$temp
        cat $temp
    rm $temp
end

Llamar con run-silent somecommand &(donde el seguimiento &hace que se ejecute en segundo plano)

Tenga en cuenta que esto tragará el código de salida original y volcará ambos stdouty stderren caso de falla. Puede personalizarlo según sea necesario.


1 Ni siquiera hay una garantía de que la salida de error no aparezca stdout, ¡algunos programas volcarán toda la salida allí!

2 Desafortunadamente, este no es siempre el caso: el código de salida está completamente controlado por el programa y algunos indicarán algunas condiciones de éxito con salidas distintas de cero. Nuevamente, consulte el manual.

Beto
fuente
ligero ajuste de peces, hay un lugar especial para poner funciones en ~ / .config / fish / functions /
Xster
12

Las utilidades de Unix envían mensajes generales stdouty mensajes de error a stderr, por lo que si solo queremos ver mensajes de error, será suficiente suprimirlos stdoutpara que solo stderrsalga a la consola.

La forma de hacer esto (en ambos bashy fish) es agregar >/dev/nullal comando. Esto canaliza stdout hacia la nada, pero stderr (con sus mensajes de error) todavía llega a la consola.

Entonces, por ejemplo:

El comando echo 1 >/dev/nullno imprime nada porque stdoutse suprime la salida normal y no se escribió nada en stderr.

El comando man doesnotexist >/dev/nullimprime un mensaje de error, porque manescribe su mensaje de error en stderr.

Maximillian Laumeister
fuente
2

Esto ejecutará el comando en segundo plano y escribirá errores en un archivo de registro mientras ignora la salida normal

    command > /dev/null 2> /tmp/example_error.log &
Genkus
fuente