( exec sh -i 3<<SCRIPT 4<&0 <&3 ⏎
echo "do this thing"
echo "do that thing"
exec 3>&- <&4
SCRIPT
)
Dies geschieht jedoch besser über ein Skript mit. exec $0.
Oder wenn einer dieser Dateideskriptoren auf ein Endgerät verweist, das derzeit nicht verwendet wird, hilft dies - Sie müssen sich daran erinnern, dass auch andere Prozesse dieses Terminal überprüfen möchten.
Übrigens, wenn Ihr Ziel, wie ich annehme, darin besteht, die Umgebung des Skripts nach dessen Ausführung zu erhalten, werden Sie wahrscheinlich viel besser bedient:
. ./script
Die Shells .dot
und bash's source
sind nicht ein und dasselbe - die .dot
Shells sind POSIX-spezifisch als spezielle eingebaute Shell spezifiziert und daher so nah wie möglich an der Garantie, obwohl dies keineswegs eine Garantie dafür ist, dass sie da sind ...
Obgleich das oben genannte mit wenig Ausgabe tun sollte, wie Sie erwarten. Zum Beispiel können Sie:
( exec sh -i 3<<SCRIPT 4<&0 <&3 ⏎
echo "do this thing"
echo "do that thing"
$(cat /path/to/script)
exec 3>&- <&4
SCRIPT
)
Die Shell führt Ihr Skript aus und kehrt zur interaktiven Eingabeaufforderung zurück - sofern Sie nicht exit
die Shell aus Ihrem Skript entfernen oder Ihren Prozess im Hintergrund ausführen -, mit der Ihre E / A verknüpft wird/dev/null.
DEMO:
% 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$
VIELE JOBS
Ich bin der Meinung, dass Sie sich ein wenig mit den integrierten Aufgabenverwaltungsoptionen der Shell vertraut machen sollten. @Kiwy und @jillagre haben dies bereits in ihren Antworten angesprochen, aber es könnte weitere Einzelheiten rechtfertigen. Und ich habe schon ein POSIX-spezifizierte spezielle Shell erwähnt eingebaut, aber set, jobs, fg,
und bg
sind ein paar mehr, und als eine andere Antwort zeigt , trap
und kill
zwei weitere noch.
Wenn Sie noch keine Sofortbenachrichtigungen zum Status gleichzeitig ausgeführter Hintergrundprozesse erhalten, liegt dies daran, dass Ihre aktuellen Shell-Optionen auf den von POSIX angegebenen Standardwert von festgelegt -m
sind. Sie können diese jedoch auch asynchron set -b
abrufen:
% 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.
Ein sehr grundlegendes Merkmal von Unix-basierten Systemen ist die Art und Weise, wie sie verarbeitet werden signals
. Ich habe einmal einen aufschlussreichen Artikel zu diesem Thema gelesen , der diesen Prozess mit Douglas Adams 'Beschreibung des Planeten NowWhat in Einklang bringt:
"In" Per Anhalter durch die Galaxis "erwähnt Douglas Adams einen extrem langweiligen Planeten, der von einer Gruppe depressiver Menschen und einer bestimmten Tierrasse mit scharfen Zähnen bewohnt wird, die mit den Menschen kommunizieren, indem sie sich sehr fest in die Oberschenkel beißen. Dies ist auffällig Ähnlich wie UNIX, bei dem der Kernel mit Prozessen kommuniziert, indem er lähmende oder tödliche Signale an sie sendet. Prozesse können einige der Signale abfangen und versuchen, sich an die Situation anzupassen, aber die meisten von ihnen tun dies nicht. "
Dies bezieht sich auf 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
Zumindest für mich beantwortete das obige Zitat viele Fragen. Zum Beispiel hatte ich es immer als sehr seltsam und überhaupt nicht intuitiv empfunden, dass ich einen dd
Prozess überwachen musste , wenn ich ihn überwachen wollte kill
. Nachdem ich das gelesen hatte, ergab es Sinn.
Ich würde sagen, die meisten von ihnen versuchen nicht aus gutem Grund , sich anzupassen - es kann weitaus ärgerlicher sein als es ein Segen, wenn eine Reihe von Prozessen Ihr Terminal mit den Informationen spammt, die die Entwickler für Sie als wichtig erachtet haben .
Je nach Terminalkonfiguration (die Sie mit überprüfen stty -a
) , CTRL+Z
ist wahrscheinlich Satz ein weiterleiten SIGTSTP
den aktuellen Vordergrundprozess Gruppenleiter, die Wahrscheinlichkeit , dass Ihr Schal ist und das sollte auch standardmäßig so konfiguriert werden , trap
dass Signal und unterbrechen Sie Ihren letzten Befehl. Wie die Antworten von @jillagre und @Kiwy zusammen zeigen, können Sie diese Funktionalität ohne weiteres an Ihren gewünschten Zweck anpassen.
SCREEN JOBS
Um diese Funktionen nutzen zu können, müssen Sie sie zunächst verstehen und ihre Handhabung an Ihre eigenen Bedürfnisse anpassen. Ich habe zum Beispiel gerade diesen Screenrc auf Github gefunden , der screen
Tastaturbelegungen für Folgendes enthält 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
Das macht es einfach, einen Prozess, der als untergeordneter screen
Prozess ausgeführt wird, oder den screen
untergeordneten Prozess selbst anzuhalten, wie Sie es wünschen.
Und gleich danach:
% fg
ODER:
% bg
Wäre Vordergrund oder Hintergrund des Prozesses, wie Sie es vorgezogen haben. Die jobs
eingebaute kann Ihnen jederzeit eine Liste dieser zur Verfügung stellen. Das Hinzufügen des -l
Operanden enthält PID-Details.