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_program
finalizar.
Estoy seguro de -c
que no es una buena manera como man bash
seys:
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_program
de vez en cuando - No quiero ponerlo en segundo plano
- Quiero quedarme en el
bash
entonces para hacer otra cosa - Quiero poder ejecutar el programa nuevamente
pty.
fg
Respuestas:
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
.dot
ybash's source
no son uno y el mismo: el shell.dot
está 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
exit
el shell de su script, es decir, o en segundo plano su proceso, que vinculará su E / S a/dev/null.
MANIFESTACIÓN:
MUCHOS
JOBS
Es 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,
ybg
son un poco más, e, como otra respuesta demuestratrap
ykill
dos 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
dd
proceso tenía quekill
hacerlo. 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+Z
es probable que esté configurado para reenviarSIGTSTP
a 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 paratrap
esa 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 JOBS
Por 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
screen
de teclas paraSIGTSTP
:Eso facilitaría la suspensión de un proceso que se ejecuta como un
screen
proceso secundario oscreen
proceso 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
jobs
incorporado puede proporcionarle una lista de estos en cualquier momento. Agregar el-l
operando 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_program
y, después de lassome_program
salidas, 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_program
primero y luego se ejecuteexec </dev/tty
después. Entonces, en lugar de continuar leyendo comandos de la cadena que lo pasamos, bash comenzará a leer/dev/tty
.Esto
-i
se 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
~/.bashrc
archivo.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_COMMAND
es 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 -i
lugar. Luego está lo/dev/tty
que 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/tty
no 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+C
es solo un efecto secundario de la configuración predeterminada de su terminal para interpretarlo como aSIGINT
. Puede modificar eso como lo hará constty
.SIGINT
estátrapped
arriba 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-file
estaba destinado a leer archivos de inicialización de todo el sistema,/etc/bash.bashrc
por 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
fg
comando y^+z
volver a ponerlo en segundo plano.fuente
bash
o 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
screen
pero 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
.