( exec sh -i 3<<SCRIPT 4<&0 <&3 ⏎
echo "do this thing"
echo "do that thing"
exec 3>&- <&4
SCRIPT
)
Це краще зробити зі сценарію, хоча за допомогою exec $0.
Or, якщо один з цих дескрипторів файлів спрямовує до термінального пристрою, який наразі не використовується, це допоможе - ви повинні пам’ятати, що інші процеси теж хочуть перевірити цей термінал.
І до речі, якщо ваша мета, як я припускаю, це зберегти середовище сценарію після його виконання, вам, ймовірно, буде набагато краще:
. ./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
швидше за все , буде встановлено, щоб переслати a SIGTSTP
поточному лідеру групи переднього плану, який, ймовірно, ваша оболонка, і який також повинен бути налаштований за замовчуванням на trap
цей сигнал і призупинити останню команду. Знову ж таки, як показують відповіді @jillagre та @Kiwy разом, жодне перешкоджає вам адаптувати цю функціональність за вашим призначенням.
SCREEN JOBS
Отож, щоб скористатися цими можливостями, очікується, що ви спочатку їх зрозумієте та налаштуєте їх обробку під власні потреби. Наприклад, я щойно знайшов цей скриншот на 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.