( exec sh -i 3<<SCRIPT 4<&0 <&3 ⏎
echo "do this thing"
echo "do that thing"
exec 3>&- <&4
SCRIPT
)
Il est préférable de le faire à partir d'un script avec exec $0.Or ou si l'un de ces descripteurs de fichiers dirige vers un périphérique terminal qui n'est pas actuellement utilisé, cela vous aidera - vous devez vous rappeler que d'autres processus veulent également vérifier ce terminal.
Et au fait, si votre objectif est, comme je le suppose, de préserver l'environnement du script après l'avoir exécuté, vous seriez probablement beaucoup mieux servi avec:
. ./script
Le shell .dotet bash's sourcene sont pas une seule et même chose - le shell .dotest POSIX spécifié comme un shell spécial intégré et est donc aussi proche que possible de la garantie, bien que ce ne soit en aucun cas une garantie qu'il sera là ...
Bien que ce qui précède devrait faire ce que vous attendez avec peu de problèmes. Par exemple, vous pouvez:
( exec sh -i 3<<SCRIPT 4<&0 <&3 ⏎
echo "do this thing"
echo "do that thing"
$(cat /path/to/script)
exec 3>&- <&4
SCRIPT
)
Le shell exécutera votre script et vous renverra à l'invite interactive - tant que vous évitez d' exitutiliser le shell de votre script, c'est-à-dire, ou d'arrière-plan de votre processus - qui liera vos E / S à/dev/null.
DÉMO:
% 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$
BEAUCOUP JOBS
Je pense que vous devriez vous familiariser un peu avec les options de gestion des tâches intégrées du shell. @Kiwy et @jillagre ont tous deux déjà abordé ce sujet dans leurs réponses, mais cela pourrait justifier des détails supplémentaires. Et j'ai déjà mentionné un shell spécial spécifié par POSIX intégré, maisset, jobs, fg, et il bgy en a quelques autres, et, comme une autre réponse le démontre, trapet killdeux autres encore.
Si vous ne recevez pas déjà des notifications instantanées sur l'état des processus en arrière-plan exécutés simultanément, c'est parce que vos options de shell actuelles sont définies sur la valeur par défaut spécifiée par POSIX -m, mais vous pouvez les obtenir de manière asynchrone avec 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.
Une caractéristique très fondamentale des systèmes basés sur Unix est leur méthode de gestion des processus signals. J'ai lu une fois un article éclairant sur le sujet qui compare ce processus à la description de la planète par Douglas Adams NowWhat:
"Dans le Guide de l'auto-stoppeur de la galaxie, Douglas Adams mentionne une planète extrêmement terne, habitée par un groupe d'humains déprimés et une certaine race d'animaux aux dents pointues qui communiquent avec les humains en les mordant très fort dans les cuisses. C'est frappant similaire à UNIX, dans lequel le noyau communique avec les processus en leur envoyant des signaux paralysants ou mortels. Les processus peuvent intercepter certains des signaux et essayer de s'adapter à la situation, mais la plupart ne le font pas. "
Il s'agit de 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
Au moins pour moi, la citation ci-dessus a répondu à beaucoup de questions. Par exemple, j'avais toujours considéré comme très étrange et pas du tout intuitif que si je voulais surveiller undd processus, je devais le faire kill. Après avoir lu cela, cela avait du sens.
Je dirais que la plupart d'entre eux n'essaient pas de s'adapter pour une bonne raison - cela peut être bien plus ennuyeux que ce serait une aubaine d'avoir un tas de processus spammant votre terminal avec les informations que leurs développeurs pensaient avoir été importantes pour vous .
En fonction de la configuration de votre terminal (avec laquelle vous pouvez vérifier stty -a) , CTRL+Zest probablement défini pour transmettre un SIGTSTPau leader du groupe de processus de premier plan actuel, qui est probablement votre shell, et qui devrait également être configuré par défaut pourtrap ce signal et suspendre votre dernière commande. Encore une fois, comme le montrent les réponses de @jillagre et @Kiwy, rien ne vous empêche d'adapter cette fonctionnalité à votre objectif comme vous le souhaitez.
SCREEN JOBS
Donc, pour tirer parti de ces fonctionnalités, vous devez d'abord les comprendre et personnaliser leur gestion en fonction de vos propres besoins. Par exemple, je viens de trouver ce screenrc sur Github qui inclut des screenraccourcis clavier pour 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
Cela simplifierait la suspension d'un processus exécuté en tant qu'enfant screen processus ou du screenprocessus enfant lui-même comme vous le souhaitiez.
Et immédiatement après:
% fg
OU:
% bg
Mettre en avant ou en arrière-plan le processus selon vos préférences. La fonction jobsintégrée peut vous fournir une liste de ces éléments à tout moment. L'ajout de l' -lopérande inclura les détails du pid.