( exec sh -i 3<<SCRIPT 4<&0 <&3 ⏎
echo "do this thing"
echo "do that thing"
exec 3>&- <&4
SCRIPT
)
Это лучше сделать из скрипта, хотя с помощью exec $0.
Или, если один из этих файловых дескрипторов направляет на терминальное устройство, которое в данный момент не используется, это поможет - вы должны помнить, что другие процессы тоже хотят проверить этот терминал.
И, кстати, если ваша цель, как я полагаю, заключается в том, чтобы сохранить среду сценария после ее выполнения, вам, вероятно, будет гораздо лучше справляться с:
. ./script
Оболочки .dot
и bash's source
не одно и то же - оболочка - .dot
это POSIX, заданная как специальная встроенная оболочка, и поэтому она настолько близка к гарантированности, насколько вы можете получить, хотя это ни в коем случае не является гарантией того, что она будет там ...
Хотя вышесказанное должно делать, как вы ожидаете, с небольшой проблемой. Например, вы можете:
( exec sh -i 3<<SCRIPT 4<&0 <&3 ⏎
echo "do this thing"
echo "do that thing"
$(cat /path/to/script)
exec 3>&- <&4
SCRIPT
)
Оболочка запустит ваш скрипт и вернет вас к интерактивному приглашению - при условии, что вы исключите exit
оболочку из вашего скрипта, то есть не создадите фоновый режим для вашего процесса - который свяжет ваш ввод / вывод/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$
МНОГИЕ JOBS
По моему мнению, вам следует немного ближе познакомиться со встроенными в оболочку параметрами управления задачами. @Kiwy и @jillagre уже упоминали об этом в своих ответах, но это может потребовать дополнительных подробностей. И я уже говорил один POSIX-указанную специальную оболочку встроенный, но set, jobs, fg,
и bg
еще несколько, и, как показывает другой ответ trap
и kill
еще два по- прежнему.
Если вы еще не получаете мгновенные уведомления о состоянии одновременно запущенных фоновых процессов, это потому, что ваши текущие параметры оболочки установлены на POSIX-значение по умолчанию -m
, но вы можете получить их асинхронно с помощью 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.
Очень фундаментальной особенностью Unix-систем является их метод обработки signals
. Однажды я прочитал поучительную статью на эту тему, которая сравнивает этот процесс с описанием планеты Дугласом Адамсом. Что:
«В« Путеводителе автостопом по галактике »Дуглас Адамс упоминает о крайне скучной планете, населенной кучкой людей, страдающих депрессией, и определенной породой животных с острыми зубами, которые общаются с людьми, сильно кусая их в бедра. Это поразительно аналогично UNIX, в котором ядро взаимодействует с процессами, посылая им парализующие или смертельные сигналы. Процессы могут перехватывать некоторые сигналы и пытаться адаптироваться к ситуации, но большинство из них этого не делают ».
Это относится к 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
По крайней мере для меня приведенная цитата ответила на множество вопросов. Например, я всегда считал это очень странным и совсем не интуитивным, что, если я хотел контролировать dd
процесс, я должен был kill
это делать . После прочтения это имело смысл.
Я бы сказал, что большинство из них не пытаются адаптироваться по уважительной причине - это может быть гораздо большим раздражением, чем благом иметь кучу процессов, спамующих ваш терминал любой информацией, которую их разработчики посчитали важной для вас. ,
В зависимости от конфигурации вашего терминала (которую вы можете проверить stty -a
) , CTRL+Z
скорее всего, он настроен на перенаправление SIGTSTP
текущего лидера группы процессов переднего плана, который, вероятно, является вашей оболочкой, и который также должен быть настроен по умолчанию на trap
этот сигнал и приостановить вашу последнюю команду. Опять же, как показывают ответы @jillagre и @Kiwy вместе, вы не сможете помешать вам адаптировать эту функциональность к вашим целям по вашему усмотрению.
SCREEN JOBS
Поэтому, чтобы воспользоваться этими функциями, вы должны сначала понять их и настроить их обработку в соответствии с вашими потребностями. Например, я только что нашел этот screenrc на Github, который включает screen
привязки клавиш для 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
Это упростит приостановку процесса, выполняющегося как дочерний screen
процесс, или самого screen
дочернего процесса, как вы пожелаете.
И сразу после этого:
% fg
ИЛИ:
% bg
Будет ли на переднем плане или фона процесс, как вы предпочитаете. jobs
Встроенный может предоставить вам список из них в любой момент. Добавление -l
операнда будет включать в себя детали pid.