¿Cómo uso el comando nohup sin obtener nohup.out?


309

Tengo un problema con el comando nohup.

Cuando ejecuto mi trabajo, tengo muchos datos. La salida nohup.out se vuelve demasiado grande y mi proceso se ralentiza. ¿Cómo puedo ejecutar este comando sin obtener nohup.out?


Respuestas:


612

El nohupcomando solo escribe nohup.outsi la salida iría a la terminal. Si ha redirigido la salida del comando a otro lugar, incluido /dev/null, es a donde va.

 nohup command >/dev/null 2>&1   # doesn't create nohup.out

Si está utilizando nohup, eso probablemente significa que desea ejecutar el comando en segundo plano colocando otro &al final de todo:

 nohup command >/dev/null 2>&1 & # runs in background, still doesn't create nohup.out

En Linux, ejecutar un trabajo con también nohupcierra automáticamente su entrada. En otros sistemas, especialmente BSD y macOS, ese no es el caso, por lo tanto, cuando se ejecuta en segundo plano, es posible que desee cerrar la entrada manualmente. Si bien cerrar la entrada no tiene ningún efecto en la creación o no nohup.out, evita otro problema: si un proceso en segundo plano intenta leer algo de la entrada estándar, se detendrá, esperando que lo devuelva al primer plano y escriba algo. Entonces la versión extra segura se ve así:

nohup command </dev/null >/dev/null 2>&1 & # completely detached from terminal 

Sin embargo, tenga en cuenta que esto no impide que el comando acceda directamente al terminal, ni lo elimina del grupo de procesos de su shell. Si desea hacer lo último, y está ejecutando bash, ksh o zsh, puede hacerlo ejecutando disownsin argumento como el siguiente comando. Eso significará que el proceso en segundo plano ya no está asociado con un "trabajo" de shell y no tendrá ninguna señal enviada desde el shell. (Tenga en cuenta la distinción: un disownproceso ed no recibe señales enviadas automáticamente por su shell principal, pero sin nohupél, aún recibirá una HUPseñal enviada por otros medios, como un killcomando manual . Un nohupproceso ed ignora todas y cada una de las HUPseñales, no importa cómo se envíen).

Explicación:

En los sistemas Unixy, cada fuente de entrada o destino de salida tiene un número asociado llamado "descriptor de archivo" o "fd" para abreviar. Cada programa en ejecución ("proceso") tiene su propio conjunto de estos, y cuando se inicia un nuevo proceso, ya tiene tres de ellos abiertos: "entrada estándar", que es fd 0, está abierta para que el proceso lea, mientras "salida estándar" (fd 1) y "error estándar" (fd 2) están abiertos para que pueda escribir. Si solo ejecuta un comando en una ventana de terminal, de manera predeterminada, todo lo que escribe va a su entrada estándar, mientras que tanto su salida estándar como su error estándar se envían a esa ventana.

Pero puede pedirle al shell que cambie a dónde apuntan algunos o todos esos descriptores de archivos antes de ejecutar el comando; eso es lo que el cambio de dirección ( <, <<, >, >>) y el tubo ( |operadores) lo hacen.

La tubería es la más simple de estas ... command1 | command2organiza la salida estándar de command1para alimentar directamente a la entrada estándar de command2. Esta es una disposición muy útil que ha llevado a un patrón de diseño particular en las herramientas de UNIX (y explica la existencia de un error estándar, que permite que un programa envíe mensajes al usuario a pesar de que su salida va al siguiente programa en la tubería) . Pero solo puede canalizar la salida estándar a la entrada estándar; no puede enviar ningún otro descriptor de archivo a una tubería sin un poco de malabarismo.

Los operadores de redirección son más amigables ya que le permiten especificar qué descriptor de archivo redirigir. Entonces 0<infilelee la entrada estándar del archivo nombrado infile, mientras 2>>logfileagrega el error estándar al final del archivo nombrado logfile. Si no especifica un número, la redirección de entrada predeterminada es fd 0 ( <es lo mismo que 0<), mientras que la redirección de salida es fd 1 ( >es igual que 1>).

Además, puede combinar los descriptores de archivos: 2>&1significa "enviar un error estándar donde sea que vaya la salida estándar". Eso significa que obtienes una única secuencia de salida que incluye tanto la salida estándar como el error estándar entremezclado sin forma de separarlos más, pero también significa que puedes incluir el error estándar en una tubería.

Entonces, la secuencia >/dev/null 2>&1significa "enviar salida estándar a /dev/null" (que es un dispositivo especial que simplemente desecha lo que sea que le escribas) "y luego enviar un error estándar a donde sea que vaya la salida estándar" (que nos aseguramos de que fuera /dev/null). Básicamente, "deseche lo que este comando escriba en cualquiera de los descriptores de archivo".

Cuando nohupdetecta que ni su error estándar ni su salida están conectados a un terminal, no se molesta en crear nohup.out, pero supone que la salida ya está redirigida a donde el usuario quiere que vaya.

El /dev/nulldispositivo también funciona para entrada; si ejecuta un comando con </dev/null, cualquier intento de ese comando de leer desde la entrada estándar encontrará instantáneamente el final del archivo. Tenga en cuenta que la sintaxis de fusión no tendrá el mismo efecto aquí; solo funciona para apuntar un descriptor de archivo a otro abierto en la misma dirección (entrada o salida). El shell le permitirá hacerlo >/dev/null <&1, pero eso termina creando un proceso con un descriptor de archivo de entrada abierto en una secuencia de salida, por lo que en lugar de simplemente presionar el final del archivo, cualquier intento de lectura provocará un error fatal de "descriptor de archivo inválido".


1
En cuanto a nohup"si el proceso luego trata de leer algo de la entrada estándar, se detendrá, esperando que lo devuelva al primer plano y escriba algo". Parece incorrecto En cambio, nohup cierra la entrada estándar (el programa no podrá leer ninguna entrada, incluso si se ejecuta en primer plano. No se detiene, pero recibirá un código de error o EOF).
Tim

1
@Tim: esa respuesta es correcta para Linux, pero no para BSD u OS X, en la que nohupno se cierra la entrada estándar automáticamente. Tenga en cuenta que nohupno es un shell incorporado sino una utilidad binaria.
Mark Reed

nohup es parte de coreutils. ¿Quiere decir que la implementación de nohupes diferente para Linux y para BSD u OS X?
Tim

Si. El nombre "coreutils" se refiere a un paquete GNU. Pero BSD, OS X, SmartOS / Illumos y muchos Unix comerciales, básicamente aquellos que han existido por más tiempo que GNU, tienen utilidades principales que no son GNU. awkes diferente, sedes diferente, nohupes diferente ...
Mark Reed

¿Por qué escribiste "extra seguro" </dev/null? También vea 0>/dev/null unix.stackexchange.com/a/266247
Tim

68
nohup some_command > /dev/null 2>&1&

¡Eso es todo lo que necesitas hacer!


44
Hubo otra respuesta que casi tenía esta misma cosa, pero no tenían el "&" extra al final.
11101101b

10
El &en el evitará que necesite usar ctrl-c, si eso es importante para usted.
SunSparc

1
La capacidad de correr en BG es muy útil
ist_lion

Esto solo es útil si no le preocupa la captura de some_commandresultados, incluido el error.
wulfgarpro

12

¿Has intentado redirigir las tres secuencias de E / S:

nohup ./yourprogram > foo.out 2> foo.err < /dev/null &

1
¿No debería ser >/ dev / null en lugar de </ dev / null?
Scott Chu

3
@ScottChu < /dev/nullredirige la entrada estándar para nohup. Linux no requiere esto, pero POSIX permite un comportamiento donde nohupno se puede ejecutar en segundo plano si su entrada estándar está conectada al terminal. Ejemplos de tales sistemas son BSD y OS X.
Mikko Rantalainen

8

Es posible que desee utilizar el programa de separación . Lo usa como nohuppero no produce un registro de salida a menos que se lo indique. Aquí está la página del manual:

NAME
       detach - run a command after detaching from the terminal

SYNOPSIS
       detach [options] [--] command [args]

       Forks  a  new process, detaches is from the terminal, and executes com‐
       mand with the specified arguments.

OPTIONS
       detach recognizes a couple of options, which are discussed below.   The
       special  option -- is used to signal that the rest of the arguments are
       the command and args to be passed to it.

       -e file
              Connect file to the standard error of the command.

       -f     Run in the foreground (do not fork).

       -i file
              Connect file to the standard input of the command.

       -o file
              Connect file to the standard output of the command.

       -p file
              Write the pid of the detached process to file.

EXAMPLE
       detach xterm

       Start an xterm that will not be closed when the current shell exits.

AUTHOR
       detach was written by Robbert Haarman.  See  http://inglorion.net/  for
       contact information.

Tenga en cuenta que no tengo afiliación con el autor del programa. Solo soy un usuario satisfecho del programa.


2
El enlace no está roto y ese repositorio de git es antiguo. No incluye la v0.2.3 actual.
Dan D.

5

El siguiente comando le permitirá ejecutar algo en segundo plano sin obtener nohup.out:

nohup command |tee &

De esta manera, podrá obtener la salida de la consola mientras ejecuta el script en el servidor remoto: ingrese la descripción de la imagen aquí


4
sudo bash -c "nohup /opt/viptel/viptel_bin/log.sh $* &> /dev/null"  &

Redirigir la salida de sudo hace que sudo vuelva a buscar la contraseña, por lo que se necesita un mecanismo incómodo para hacer esta variante.


1

Si tiene un shell BASH en su mac / linux frente a usted, pruebe los siguientes pasos para comprender la redirección prácticamente:

Cree un script de 2 líneas llamado zz.sh

#!/bin/bash
echo "Hello. This is a proper command"
junk_errorcommand
  • La salida del comando echo entra en STDOUT filestream (descriptor de archivo 1).
  • La salida del comando de error va a STDERR filestream (descriptor de archivo 2)

Actualmente, simplemente ejecutar el script envía tanto STDOUT como STDERR a la pantalla.

./zz.sh

Ahora comience con la redirección estándar:

zz.sh > zfile.txt

En lo anterior, "echo" (STDOUT) entra en zfile.txt. Mientras que "error" (STDERR) se muestra en la pantalla.

Lo anterior es lo mismo que:

zz.sh 1> zfile.txt

Ahora puede intentar lo contrario y redirigir el "error" STDERR al archivo. El comando STDOUT from "echo" va a la pantalla.

zz.sh 2> zfile.txt

Combinando los dos anteriores, obtienes:

zz.sh 1> zfile.txt 2>&1

Explicación:

  • PRIMERO, envíe STDOUT 1 a zfile.txt
  • ENTONCES, envíe STDERR 2 a STDOUT 1 (usando el puntero & 1).
  • Por lo tanto, tanto 1 como 2 van al mismo archivo (zfile.txt)

Eventualmente, puede empaquetar todo dentro del comando nohup y ejecutarlo en segundo plano:

nohup zz.sh 1> zfile.txt 2>&1&

1

Puede ejecutar el siguiente comando.

nohup <your command> & >  <outputfile> 2>&1 &

por ejemplo, tengo un comando nohup dentro del script

./Runjob.sh > sparkConcuurent.out 2>&1
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.