Me gustaría ejecutar algo como esto:
bash -c "some_program with its arguments"
pero para que un bash interactivo siga ejecutándose después de some_programfinalizar.
Estoy seguro de -cque no es una buena manera como man bashseys:
Un shell interactivo es uno que se inicia sin argumentos sin opciones y sin la opción -c
Entonces, ¿cómo hacer esto?
El objetivo principal se describe aquí.
NOTA
- Necesito terminar
some_programde vez en cuando - No quiero ponerlo en segundo plano
- Quiero quedarme en el
bashentonces para hacer otra cosa - Quiero poder ejecutar el programa nuevamente

pty.fgRespuestas:
Sin embargo, esto se hace mejor desde una secuencia de comandos con
exec $0.O si uno de esos descriptores de archivo dirige a un dispositivo terminal que no se está utilizando actualmente, será de ayuda; debe recordar, otros procesos también quieren verificar ese terminal.Y, por cierto, si su objetivo es, como supongo que es, preservar el entorno del script después de ejecutarlo, probablemente sea mucho mejor servido con:
Los shell
.dotybash's sourceno son uno y el mismo: el shell.dotestá POSIX especificado como un shell especial incorporado y, por lo tanto, está lo más cerca posible de estar garantizado, aunque esto de ninguna manera es una garantía de que estará allí ...Aunque lo anterior debería hacer lo que espera con poco problema. Por ejemplo, puedes:
El shell ejecutará su script y lo regresará a la solicitud interactiva, siempre que evite
exitel shell de su script, es decir, o en segundo plano su proceso, que vinculará su E / S a/dev/null.MANIFESTACIÓN:
MUCHOS
JOBSEs mi opinión que debería familiarizarse un poco más con las opciones de administración de tareas integradas del shell. @Kiwy y @jillagre ya han mencionado esto en sus respuestas, pero podría justificar más detalles. Y ya he mencionado un proyectil especial especificado por POSIX incorporado, pero
set, jobs, fg,ybgson un poco más, e, como otra respuesta demuestratrapykilldos más todavía.Si aún no recibe notificaciones instantáneas sobre el estado de la ejecución simultánea de procesos en segundo plano, es porque sus opciones de shell actuales están configuradas en el valor predeterminado especificado por POSIX
-m, pero en su lugar puede obtenerlas de forma asincrónicaset -b:Una característica muy fundamental de los sistemas basados en Unix es su método de proceso de manejo
signals. Una vez leí un artículo esclarecedor sobre el tema que compara este proceso con la descripción de Douglas Adams del planeta NowWhat:Esto se refiere a
kill signals.Al menos para mí, la cita anterior respondió muchas preguntas. Por ejemplo, siempre consideré muy extraño y nada intuitivo que si quería monitorear un
ddproceso tenía quekillhacerlo. Después de leer eso tenía sentido.Diría que la mayoría de ellos no intentan adaptarse por una buena razón: puede ser una molestia mucho mayor de lo que sería una bendición tener un montón de procesos enviando spam a su terminal con cualquier información que sus desarrolladores pensaran que podría haber sido importante para usted .
Dependiendo de la configuración de su terminal (con la que puede verificar
stty -a) ,CTRL+Zes probable que esté configurado para reenviarSIGTSTPa al líder actual del grupo de procesos en primer plano, que probablemente sea su shell, y que también debe configurarse de manera predeterminada paratrapesa señal y suspender su último comando. Nuevamente, como muestran las respuestas de @jillagre y @Kiwy juntas, no hay impedimento para adaptar esta funcionalidad a su propósito como prefiera.SCREEN JOBSPor lo tanto, para aprovechar estas características, se espera que primero las comprenda y personalice su manejo según sus propias necesidades. Por ejemplo, acabo de encontrar este screenrc en Github que incluye combinaciones
screende teclas paraSIGTSTP:Eso facilitaría la suspensión de un proceso que se ejecuta como un
screenproceso secundario oscreenproceso secundario en sí mismo como lo desee.E inmediatamente después:
O:
Pondría en primer plano o en segundo plano el proceso como prefiera. El
jobsincorporado puede proporcionarle una lista de estos en cualquier momento. Agregar el-loperando incluirá detalles pid.fuente
Aquí hay una solución más corta que logra lo que desea, pero podría no tener sentido a menos que comprenda el problema y cómo funciona bash:
Esto lanzará un shell bash, comenzará
some_programy, después de lassome_programsalidas, se lo colocará en un shell bash.Básicamente, lo que estamos haciendo es alimentar a bash con una cadena en su STDIN. Esa cuerda es
some_program with its arguments; exec </dev/tty. Esto le dice a bash que se iniciesome_programprimero y luego se ejecuteexec </dev/ttydespués. Entonces, en lugar de continuar leyendo comandos de la cadena que lo pasamos, bash comenzará a leer/dev/tty.Esto
-ise debe a que cuando se inicia bash, verifica si STDIN es un tty, y cuando se inicia no lo es. Pero más tarde lo será, así que lo forzamos al modo interactivo.Otra solución
Otra idea que pensé que sería muy portátil sería agregar lo siguiente al final de su
~/.bashrcarchivo.Luego, cuando desee iniciar un shell con un comando primero, simplemente haga:
Explicación:
La mayor parte de esto debería ser obvio, pero la resonancia para el cambio de nombre de la variable es para que podamos localizar la variable. Como
$START_COMMANDes una variable exportada, será heredada por cualquier hijo del shell, y si otro shell bash es uno de esos hijos, ejecutará el comando nuevamente. Entonces asignamos el valor a una nueva variable no exportada ($start_command) y eliminamos la anterior.fuente
<<<no es POSIX, pero podría en suecho "string here" | bash -ilugar. Luego está lo/dev/ttyque es una cosa de Linux. Pero podría duplicar el FD antes de iniciar bash, y luego volver a abrir STDIN, que se parece a lo que está haciendo, pero opté por mantener las cosas simples./dev/ttyno es una cosa de Linux, pero definitivamente POSIX.Esto debería funcionar:
Editar:
Aquí hay un nuevo intento después de su actualización:
Use ControlC, se le presentará este pequeño menú:
Ese es el caso.
Seleccione la opción "bash"
Seleccione la opción "reiniciar"
fuente
CTRL+Ces solo un efecto secundario de la configuración predeterminada de su terminal para interpretarlo como aSIGINT. Puede modificar eso como lo hará constty.SIGINTestátrappedarriba con2.Puede hacerlo pasando su script como un archivo de inicialización:
O puede pasarlo en la línea de comando:
Tenga en cuenta que
--init-fileestaba destinado a leer archivos de inicialización de todo el sistema,/etc/bash.bashrcpor lo que es posible que desee 'source' estos en su secuencia de comandos.fuente
Realmente no veo el punto de hacer esto, ya que ya vuelves a un shell después de ejecutar este programa. Sin embargo, podrías hacer esto:
Esto lanzará una fiesta interactiva después de que se ejecute el programa.
fuente
Puede poner el comando en segundo plano para mantener abierto su bash actual:
Para volver a la ejecución, puede usar el
fgcomando y^+zvolver a ponerlo en segundo plano.fuente
basho no, estás usando un shell muy extraño para mí si no puede manejar el fondo del proceso. Y estoy de acuerdo con Kiwi: esa información le serviría mejor si estuviera en su pregunta.Es posible que desee utilizar la pantalla para ejecutar el comando. Luego puede volver a adjuntar a la sesión una vez que se complete el comando.
Alternativamente, simplemente ejecute el comando en segundo plano
some_program with its arguments&. Esto le permitirá volver a ejecutar el comando y obtener el estado del comando una vez que se haya completado.fuente
screenpero ponerlo en segundo plano no es útil para mí; a veces necesito terminar el programa, hacer otra cosa y ejecutarlo nuevamente. Y el objetivo principal es hacer esto rápido.kill %okill %1.