Me resulta difícil formular la pregunta con precisión, pero daré lo mejor de mí. Yo uso dwm
como mi administrador de ventanas predeterminado ydmenu
como mi lanzador de aplicaciones. Apenas uso aplicaciones GUI aparte de mi navegador. La mayor parte de mi trabajo se realiza directamente desde la línea de comandos. Además, soy un gran admirador del minimalismo con respecto a los sistemas operativos, aplicaciones, etc. Una de las herramientas de las que nunca me deshice fue un lanzador de aplicaciones. Principalmente porque no tengo una comprensión precisa de cómo funcionan los lanzadores de aplicaciones / qué hacen. Incluso la búsqueda exhaustiva en Internet solo muestra una vaga explicación. Lo que quiero hacer es deshacerme incluso de mi iniciador de aplicaciones porque, aparte de engendrar la aplicación, no tengo absolutamente ninguna utilidad. Para hacer esto, me gustaría saber cómo iniciar "correctamente" las aplicaciones desde el shell. Por lo que el significado de "correctamente" se puede aproximar por "como lo haría un lanzador de aplicaciones".
Conozco las siguientes formas de generar procesos desde el shell:
exec /path/to/Program
reemplazar shell con el comando especificado sin crear un nuevo procesosh -c /path/to/Program
iniciar proceso dependiente de shell/path/to/Program
iniciar proceso dependiente de shell/path/to/Program 2>&1 &
lanzar proceso independiente de shellnohup /path/to/Program &
lanzar un proceso independiente de shell y redirigir la salidanohup.out
Actualización 1: puedo ilustrar lo que dmenu
hace, por ejemplo , reconstruirlo desde llamadas repetidas a ps -efl
diferentes condiciones. Genera un nuevo shell /bin/bash
y, como hijo de este shell, la aplicación /path/to/Program
. Mientras el niño esté cerca, la concha estará alrededor. (La forma en que maneja esto está más allá de mí ...) Por el contrario, si emite nohup /path/to/Program &
un shell /bin/bash
, el programa se convertirá en el hijo de este shell, PERO si sale de este shell, el padre del programa será el proceso superior. Entonces, si el primer proceso fue, por ejemplo, /sbin/init verbose
y lo ha sido PPID 1
, será el padre del programa. Esto es lo que intenté explicar usando un gráfico: chromium
se lanzó a través de dmenu
, firefox
se lanzó usando exec firefox & exit
:
systemd-+-acpid
|-bash---chromium-+-chrome-sandbox---chromium-+-chrome-sandbox---nacl_helper
| | `-chromium---5*[chromium-+-{Chrome_ChildIOT}]
| | |-{Compositor}]
| | |-{HTMLParserThrea}]
| | |-{OptimizingCompi}]
| | `-3*[{v8:SweeperThrea}]]
| |-chromium
| |-chromium-+-chromium
| | |-{Chrome_ChildIOT}
| | `-{Watchdog}
| |-{AudioThread}
| |-3*[{BrowserBlocking}]
| |-{BrowserWatchdog}
| |-5*[{CachePoolWorker}]
| |-{Chrome_CacheThr}
| |-{Chrome_DBThread}
| |-{Chrome_FileThre}
| |-{Chrome_FileUser}
| |-{Chrome_HistoryT}
| |-{Chrome_IOThread}
| |-{Chrome_ProcessL}
| |-{Chrome_SafeBrow}
| |-{CrShutdownDetec}
| |-{IndexedDB}
| |-{LevelDBEnv}
| |-{NSS SSL ThreadW}
| |-{NetworkChangeNo}
| |-2*[{Proxy resolver}]
| |-{WorkerPool/1201}
| |-{WorkerPool/2059}
| |-{WorkerPool/2579}
| |-{WorkerPool/2590}
| |-{WorkerPool/2592}
| |-{WorkerPool/2608}
| |-{WorkerPool/2973}
| |-{WorkerPool/2974}
| |-{chromium}
| |-{extension_crash}
| |-{gpu-process_cra}
| |-{handle-watcher-}
| |-{inotify_reader}
| |-{ppapi_crash_upl}
| `-{renderer_crash_}
|-2*[dbus-daemon]
|-dbus-launch
|-dhcpcd
|-firefox-+-4*[{Analysis Helper}]
| |-{Cache I/O}
| |-{Cache2 I/O}
| |-{Cert Verify}
| |-3*[{DOM Worker}]
| |-{Gecko_IOThread}
| |-{HTML5 Parser}
| |-{Hang Monitor}
| |-{Image Scaler}
| |-{JS GC Helper}
| |-{JS Watchdog}
| |-{Proxy R~olution}
| |-{Socket Thread}
| |-{Timer}
| |-{URL Classifier}
| |-{gmain}
| |-{localStorage DB}
| |-{mozStorage #1}
| |-{mozStorage #2}
| |-{mozStorage #3}
| |-{mozStorage #4}
| `-{mozStorage #5}
|-gpg-agent
|-login---bash---startx---xinit-+-Xorg.bin-+-xf86-video-inte
| | `-{Xorg.bin}
| `-dwm-+-dwmstatus
| `-xterm---bash-+-bash
| `-pstree
|-systemd---(sd-pam)
|-systemd-journal
|-systemd-logind
|-systemd-udevd
|-wpa_actiond
`-wpa_supplicant
Actualización 2: Supongo que la pregunta también se puede resumir en: ¿Cuál debería ser el padre de un proceso? ¿Debería ser, por ejemplo, un shell o debería ser el init
proceso, es decir, el proceso con PID 1
?
init
, a lo que la respuesta podría ser ... ¿tal vez? depende de cómo / si planeas hablar con él, quéinit
usas y dónde están los canales de datos. En general, esas cosas tenderán a resolverse por sí solas, para esoinit
están. En cualquier caso, generalmente cuando demoniza un proceso entoncesinit
. O si quieres control de trabajo, shell actual.dmenu
y veré cómo me llevo con lo que aprendí. Me pareceexec /path/to/Program & exit
o/bin/bash -c /path/to/Program & exit
para ser bastante utilizable. Pero todos ellos son,1
es decir,init
el padre de loProgram
que está bien para mí siempre que tenga sentido y no viole ningún*nix
principio básico .exec &
, creo. Por lo general, hago mis cosas desde la terminal ... tal vez te sirva de algo la pregunta de Ben Crowell aquí . Tengo una respuesta allí, pero todas son muy buenas. de todos modos, cuando creas un proceso en segundo plano y su padre muere como:sh -c 'cat & kill $$'
lo huérfano, y finalmente termina siendo cosechado. ese es el trabajo de init, por eso todos caen en él.systemd--bash--chromium
. Todos los métodos que pruebo en última instancia conducirán a un árbol de procesos de la siguiente formasystemd--chromium
cuando engendro firefox desde el shell. ¿Cómo se demoniza el caparazón aquí? No está asociado a ningún terminal.Respuestas:
Bueno, parece que lo entiendes bastante bien. Para aclarar algo de lo que tienes,
sh -c /path/to/Program
es bastante similar adonde inicia un nuevo proceso de shell, proporcione la ruta de comando de la aplicación al nuevo shell y luego deje que el nuevo shell finalice. He mostrado el nuevo shell dando un mensaje diferente con fines ilustrativos; Esto probablemente no sucedería en la vida real. La construcción es principalmente útil para hacer cosas difíciles, como envolver múltiples comandos en un paquete, por lo que se ven como un solo comando (una especie de script sin nombre de un solo uso), o construir comandos complicados, posiblemente a partir de variables de shell. Casi nunca lo usaría solo para ejecutar un solo programa con argumento (s) simple (s).
sh -c "command"
2>&1
significa redirigir el error estándar a la salida estándar. Esto realmente no tiene mucho que ver con&
; más bien, lo usa cuando un comando envía mensajes de error a la pantalla incluso si dice y desea capturar los mensajes de error en el archivo.command > file
nohup.out
es un efecto secundario trivial denohup
. El propósito principal de es ejecutar de forma asincrónica (comúnmente conocido como "en segundo plano", o como un "proceso independiente de la shell", para usar sus palabras) y configurarlo para que tenga una mejor oportunidad de poder continuar ejecutándose si usted terminar el shell (por ejemplo, cerrar sesión) mientras el comando aún se está ejecutando.nohup command &
command
bash(1)
y el Manual de referencia de Bash son buenas fuentes de información.fuente
Hay varias formas de ejecutar un programa y desconectarlo de una terminal. Una es ejecutarla en el fondo de una subshell , como esta (reemplace
firefox
con su programa favorito):Otra es rechazar el proceso:
Si tiene curiosidad sobre cómo funcionan los lanzadores de aplicaciones,
dmenu
proporciona 1 script binario y 2 scripts de shelldmenu
,dmenu_path
ydmenu_run
, respectivamente.dmenu_run
canaliza la salida dedmenu_path
en dmenu, que a su vez canaliza en cualquier$SHELL
variable establecida en. Si está vacío, lo usará/bin/sh
.dmenu_path
es un poco más complejo, pero en resumen, proporciona una lista de binarios en la$PATH
variable de entorno y, si es posible, utiliza un caché.No es necesario tener programas ejecutándose en shells. Otra forma de escribir
dmenu_run
, sin conectarlo a un shell sería:fuente
Me gusta mucho la respuesta de G-Man. Pero estoy respondiendo porque creo que tienes preocupaciones confusas. Como Wayne señala, la mejor respuesta es "lo que sea que obtenga los resultados que desea".
En la gestión de procesos de Unix, cada proceso tiene un padre. La única excepción a esto es el
init
proceso que inicia el sistema operativo en el arranque. Es un comportamiento normal que un proceso padre se lleve todos sus procesos hijos cuando muere. Esto se realiza enviando la señal SIGHUP a todos los procesos secundarios; el manejo predeterminado de SIGHUP termina el proceso.La generación de shell de los procesos del usuario no es diferente de si codificara las llamadas fork (2) / exec (3) en el idioma que elija. El shell es su padre, y si el shell termina (por ejemplo, cierra la sesión), entonces el proceso o procesos secundarios que genera van con él. Los matices que describe son solo formas de modificar ese comportamiento.
exec /path/to/program
es como llamar a exec (3) . Sí, reemplazará su shell conprogram
, manteniendo cualquier padre que haya lanzado el shell.sh -c /path/to/program
crea un proceso secundario de shell que creará un proceso secundario deprogram
. Solo es valioso si en/path/to/program
realidad es una secuencia de instrucciones de script y no un archivo ejecutable. (sh /path/to/script.sh
se puede usar para ejecutar un script de shell que carece de permisos de ejecución en un shell inferior)/path/to/program
crea un proceso de "primer plano", lo que significa que el shell espera a que se complete el proceso antes de realizar cualquier otra acción. En el contexto de la llamada al sistema, es como fork (2) / exec (3) / waitpid (2) . Tenga en cuenta que el hijo hereda stdin / stdout / stderr del padre./path/to/program &
(ignorando la redirección) crea un "proceso en segundo plano". El proceso todavía es un elemento secundario del shell, pero el padre no está esperando que termine.nohup /path/to/program
invoca nohup (1) para evitar el envío de SIGHUP aprogram
si el terminal de control está cerrado. Si es en primer plano o en segundo plano es una opción (aunque lo más común es que el proceso sea de fondo). Tenga en cuenta quenohup.out
solo es la salida si no redirige stdout.Cuando pone un proceso en segundo plano, si el proceso padre muere, ocurre una de dos cosas. Si el padre es un terminal de control , SIGHUP se enviará a los niños. Si no es así, el proceso puede quedar "huérfano" y el
init
proceso lo hereda .Cuando redirige la entrada / salida / error, simplemente está conectando los descriptores de archivo que cada proceso tiene a archivos diferentes de los que hereda de su padre. Nada de esto afecta la propiedad del proceso o la profundidad del árbol (pero siempre tiene sentido redirigir los 3 lejos de una terminal para procesos en segundo plano).
Dicho todo esto, no creo que deba preocuparse por la creación de procesos por parte del shell o sub-shells o subprocesos, a menos que haya un problema específico que esté abordando en relación con la gestión de procesos.
fuente
sh -c /path/to/program
no ejecutará el programa como un script de shell si faltan los bits ejecutables, losh /path/to/program
hará.sh -c /path/to/program
solo abrirá un shell y se ejecutará/path/to/program
como un comando en ese shell, que fallará si no es ejecutable.sh -c /path/to/program
lee comandos desde/path/to/program
como entrada al shell. No requiere que el archivo tenga permiso de ejecución, pero debe ser un script de shellsh /path/to/program
hace eso. Solo lo intenté yo mismoecho echo hello world >abc.sh
, luegosh ./abc.sh
imprimohello world
, mientrassh -c ./abc.sh
dicesh: ./abc.sh: Permission denied
(que es lo mismo que si corrieras./abc.sh
directamente en el shell actual). ¿Me perdí algo? (O tal vez no mesh -c _something_
es lo mismo que escribir_something_
en el símbolo del sistema, excepto por el engendro del shell inferior. Entonces tiene razón en que fallará si falta el bit de ejecución (como un archivo). Por otro lado, puede proporcionar una serie de comandos de shell comosh -c "echo hello world"
y funcionará bien. Por lo tanto, no requiere que lo que escriba tenga el bit de ejecución (o incluso sea un archivo), solo que el intérprete de shell pueda hacer algo con él.