( exec sh -i 3<<SCRIPT 4<&0 <&3 ⏎
echo "do this thing"
echo "do that thing"
exec 3>&- <&4
SCRIPT
)
Lepiej jest to zrobić ze skryptu Jednak exec $0.
jeśli jeden z tych deskryptorów plików skieruje się do nieużywanego urządzenia końcowego, to pomoże - musisz pamiętać, że inne procesy też chcą sprawdzić ten terminal.
A tak przy okazji, jeśli twoim celem jest, jak zakładam, zachowanie środowiska skryptu po jego wykonaniu, prawdopodobnie lepiej byś był z:
. ./script
Powłoki .dot
i bash's source
nie są jednym i tym samym - powłoka .dot
jest POSIX określona jako specjalna powłoka wbudowana i dlatego jest tak blisko zagwarantowania, jak to tylko możliwe, chociaż nie jest to w żaden sposób gwarancją, że będzie tam ...
Chociaż powyższe należy zrobić bez problemu. Na przykład możesz:
( exec sh -i 3<<SCRIPT 4<&0 <&3 ⏎
echo "do this thing"
echo "do that thing"
$(cat /path/to/script)
exec 3>&- <&4
SCRIPT
)
Powłoka uruchomi skrypt i wróci do interaktywnego monitu - o ile unikasz exit
powłoki ze skryptu, czyli procesu w tle - i połączy to twoje I / O z/dev/null.
PRÓBNY:
% 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$
WIELE JOBS
Moim zdaniem powinieneś trochę lepiej zapoznać się z wbudowanymi opcjami zarządzania zadaniami powłoki. @Kiwy i @jillagre już się na to zwrócili w swoich odpowiedziach, ale może to wymagać dalszych szczegółów. A ja już wspomniano jedną POSIX określony specjalną powłokę wbudowany, ale set, jobs, fg,
i bg
to niewiele więcej, a jak pokazuje inna odpowiedź trap
i kill
są dwa jeszcze więcej.
Jeśli nie otrzymujesz natychmiastowych powiadomień o stanie równolegle działających procesów w tle, to dlatego, że twoje bieżące opcje powłoki są ustawione na wartość domyślną określoną przez POSIX -m
, ale możesz je uzyskać asynchronicznie za pomocą 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.
Bardzo podstawową cechą systemów opartych na Uniksie jest ich sposób obsługi procesu signals
. Czytałem kiedyś o pouczające artykuł na ten temat, który porównuje ten proces do opisu Douglasa Adamsa z planety NowWhat:
„W Poradniku Autostopowicza po Galaktyce Douglas Adams wspomina o wyjątkowo nudnej planecie, zamieszkałej przez grupę przygnębionych ludzi i pewną rasę zwierząt o ostrych zębach, które komunikują się z ludźmi, bardzo mocno gryząc je w uda. To uderzające podobny do UNIX-a, w którym jądro komunikuje się z procesami, wysyłając do nich paraliżujące lub śmiertelne sygnały. Procesy mogą przechwytywać niektóre sygnały i próbować dostosować się do sytuacji, ale większość z nich nie. ”
Odnosi się to do 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
Przynajmniej dla mnie powyższy cytat odpowiedział na wiele pytań. Na przykład zawsze uważałem to za bardzo dziwne i wcale nie intuicyjne, że jeśli chcę monitorować dd
proces, muszę to kill
zrobić. Po przeczytaniu miało to sens.
Powiedziałbym, że większość z nich nie próbuje się przystosować bez ważnego powodu - może to być o wiele bardziej irytujące niż byłoby dobrodziejstwem, gdyby kilka procesów spamowało twój terminal wszelkimi informacjami, które ich zdaniem deweloperów mogą być dla Ciebie ważne .
W zależności od konfiguracji terminala (którą możesz sprawdzić stty -a
) ,CTRL+Z
jest prawdopodobne jest ustawiony na przekazywanie SIGTSTP
do bieżącego lidera grupy procesów pierwszego planu, który jest prawdopodobnie twoją powłoką, i który powinien być również domyślnie skonfigurowany do trap
tego sygnału i zawiesić twoje ostatnie polecenie. Ponownie, jak pokazują razem odpowiedzi @jillagre i @Kiwy, nic nie stoi na przeszkodzie, aby dostosować tę funkcjonalność do własnych celów, tak jak lubisz.
SCREEN JOBS
Aby więc skorzystać z tych funkcji, należy je najpierw zrozumieć i dostosować ich obsługę do własnych potrzeb. Na przykład właśnie znalazłem ten screenrc na Github, który zawierascreen
powiązania klawiszy dla 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
Ułatwiłoby to zawieszenie procesu uruchomionego jako screen
proces potomny lubscreen
sam proces potomny zgodnie z życzeniem.
A zaraz potem:
% fg
LUB:
% bg
Czy planujesz lub planujesz proces tak, jak chcesz. jobs
Wbudowaną może dostarczyć listę z nich w dowolnym momencie. Dodanie -l
operandu będzie zawierało szczegóły pid.