( exec sh -i 3<<SCRIPT 4<&0 <&3 ⏎
echo "do this thing"
echo "do that thing"
exec 3>&- <&4
SCRIPT
)
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:
. ./script
Los shell .dot
y bash'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:
( exec sh -i 3<<SCRIPT 4<&0 <&3 ⏎
echo "do this thing"
echo "do that thing"
$(cat /path/to/script)
exec 3>&- <&4
SCRIPT
)
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:
% printf 'echo "%s"\n' "These lines will print out as echo" \
"statements run from my interactive shell." \
"This will occur before I'm given the prompt." >|/tmp/script
% ( exec sh -i 3<<SCRIPT 4<&0 <&3
echo "do this thing"
echo "do that thing"
$(cat /tmp/script)
exec 3>&- <&4
SCRIPT
)
sh-4.3$ echo "do this thing"
do this thing
sh-4.3$ echo "do that thing"
do that thing
sh-4.3$ echo "These lines will print out as echo"
These lines will print out as echo
sh-4.3$ echo "statements run from my interactive shell."
statements run from my interactive shell.
sh-4.3$ echo "This will occur before I'm given the prompt."
This will occur before I'm given the prompt.
sh-4.3$ exec 3>&- <&4
sh-4.3$
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,
y bg
son un poco más, e, como otra respuesta demuestra trap
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ónica set -b
:
% man set
−b This option shall be supported if the implementation supports the
User Portability Utilities option. It shall cause the shell to
notify the user asynchronously of background job completions. The
following message is written to standard error:
"[%d]%c %s%s\n", <job-number>, <current>, <status>, <job-name>
where the fields shall be as follows:
<current> The character '+' identifies the job that would be
used as a default for the fg or bg utilities; this
job can also be specified using the job_id "%+" or
"%%". The character '−' identifies the job that
would become the default if the current default job
were to exit; this job can also be specified using
the job_id "%−". For other jobs, this field is a
<space>. At most one job can be identified with '+'
and at most one job can be identified with '−'. If
there is any suspended job, then the current job
shall be a suspended job. If there are at least two
suspended jobs, then the previous job also shall be a
−m This option shall be supported if the implementation supports the
User Portability Utilities option. All jobs shall be run in their
own process groups. Immediately before the shell issues a prompt
after completion of the background job, a message reporting the
exit status of the background job shall be written to standard
error. If a foreground job stops, the shell shall write a message
to standard error to that effect, formatted as described by the
jobs utility. In addition, if a job changes status other than
exiting (for example, if it stops for input or output or is
stopped by a SIGSTOP signal), the shell shall write a similar
message immediately prior to writing the next prompt. This option
is enabled by default for interactive shells.
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:
"En The Hitchhiker's Guide to the Galaxy, Douglas Adams menciona un planeta extremadamente aburrido, habitado por un grupo de humanos deprimidos y una cierta raza de animales con dientes afilados que se comunican con los humanos mordiéndolos muy fuerte en los muslos. Esto es sorprendente similar a UNIX, en el cual el núcleo se comunica con los procesos enviándoles señales paralizantes o mortales. Los procesos pueden interceptar algunas de las señales e intentar adaptarse a la situación, pero la mayoría de ellas no lo hacen ".
Esto se refiere a kill signals
.
% kill -l
> HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH POLL PWR SYS
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 reenviar SIGTSTP
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 para trap
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 combinacionesscreen
de teclas para SIGTSTP
:
# hitting 'C-z C-z' will run Ctrl+Z (SIGTSTP, suspend as usual)
bind ^Z stuff ^Z
# hitting 'C-z z' will suspend the screen client
bind z suspend
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:
% fg
O:
% bg
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.