( exec sh -i 3<<SCRIPT 4<&0 <&3 ⏎
echo "do this thing"
echo "do that thing"
exec 3>&- <&4
SCRIPT
)
Ini lebih baik dilakukan dari skrip dengan exec $0.
Atau jika salah satu deskriptor file mengarahkan ke perangkat terminal yang saat ini sedang digunakan itu akan membantu - Anda harus ingat, proses lain ingin memeriksa terminal itu juga.
Dan omong-omong, jika tujuan Anda adalah, seperti yang saya asumsikan, untuk melestarikan lingkungan skrip setelah menjalankannya, Anda mungkin akan jauh lebih baik dilayani dengan:
. ./script
Shell .dot
dan bash's source
bukan satu dan sama - shell .dot
POSIX ditentukan sebagai shell khusus builtin dan karena itu hampir dijamin seperti yang Anda dapatkan, meskipun ini tidak berarti jaminan itu akan ada di sana ...
Meskipun hal di atas harus dilakukan seperti yang Anda harapkan dengan sedikit masalah. Misalnya, Anda dapat:
( exec sh -i 3<<SCRIPT 4<&0 <&3 ⏎
echo "do this thing"
echo "do that thing"
$(cat /path/to/script)
exec 3>&- <&4
SCRIPT
)
Shell akan menjalankan skrip Anda dan mengembalikan Anda ke prompt interaktif - selama Anda menghindari exit
shell dari skrip Anda, yaitu, atau melatar belakangi proses Anda - yang akan menautkan i / o Anda ke/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$
BANYAK JOBS
Menurut pendapat saya, Anda harus lebih terbiasa dengan opsi manajemen tugas bawaan shell. @Kiwy dan @jillagre telah menyinggung ini dalam jawaban mereka, tetapi mungkin diperlukan detail lebih lanjut. Dan saya sudah menyebutkan satu shell khusus POSIX yang ditentukan built-in, tetapi set, jobs, fg,
dan bg
beberapa lagi, dan, sebagai jawaban lain menunjukkan trap
dan kill
masih dua lagi.
Jika Anda belum menerima pemberitahuan instan tentang status menjalankan proses berlatar belakang secara bersamaan, itu karena opsi shell Anda saat ini disetel ke default POSIX yang ditentukan -m
, tetapi Anda dapat memperolehnya secara asinkron dengan 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.
Fitur yang sangat mendasar dari sistem berbasis Unix adalah metode proses penanganannya signals
. Saya pernah membaca sebuah artikel yang mencerahkan tentang subjek yang menyamakan proses ini dengan deskripsi planet Douglas Now tentang What NowHhat:
"Dalam The Hitchhiker's Guide to the Galaxy, Douglas Adams menyebutkan sebuah planet yang sangat membosankan, dihuni oleh sekelompok manusia yang tertekan dan beberapa jenis hewan dengan gigi tajam yang berkomunikasi dengan manusia dengan menggigit mereka sangat keras di paha. Ini sangat mengejutkan mirip dengan UNIX, di mana kernel berkomunikasi dengan proses dengan mengirimkan sinyal melumpuhkan atau mematikan kepada mereka. Proses dapat mencegat beberapa sinyal, dan mencoba untuk beradaptasi dengan situasi, tetapi kebanyakan dari mereka tidak. "
Ini mengacu pada 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
Setidaknya bagi saya, kutipan di atas menjawab banyak pertanyaan. Sebagai contoh, saya selalu menganggapnya sangat aneh dan sama sekali tidak intuitif bahwa jika saya ingin memonitor suatu dd
proses saya harus melakukannya kill
. Setelah membaca itu masuk akal.
Saya akan mengatakan sebagian besar dari mereka tidak mencoba untuk beradaptasi karena alasan yang baik - itu bisa menjadi gangguan yang jauh lebih besar daripada itu akan menjadi anugerah untuk memiliki banyak proses spam terminal Anda dengan informasi apa pun yang menurut pengembang mereka mungkin penting bagi Anda .
Tergantung pada konfigurasi terminal Anda (yang dapat Anda periksa dengan stty -a
) , CTRL+Z
kemungkinan diatur untuk meneruskan a SIGTSTP
ke pemimpin grup proses latar depan saat ini, yang kemungkinan shell Anda, dan yang juga harus dikonfigurasi secara default untuk trap
sinyal itu dan menangguhkan perintah terakhir Anda. Sekali lagi, seperti yang ditunjukkan oleh jawaban @jillagre dan @Kiwy bersama, tidak ada yang dapat menghentikan Anda dari menyesuaikan fungsi ini dengan tujuan yang Anda inginkan.
SCREEN JOBS
Jadi untuk memanfaatkan fitur-fitur ini, diharapkan Anda terlebih dahulu memahaminya dan menyesuaikan penanganannya dengan kebutuhan Anda sendiri. Sebagai contoh, saya baru saja menemukan screenrc ini di Github yang menyertakan screen
binding kunci untuk 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
Itu akan membuatnya menjadi masalah sederhana untuk menunda proses yang berjalan sebagai screen
proses anak atau screen
proses anak itu sendiri seperti yang Anda inginkan.
Dan segera sesudahnya:
% fg
ATAU:
% bg
Apakah latar depan atau latar belakang proses yang Anda inginkan. The jobs
built-in dapat memberikan Anda daftar ini setiap saat. Menambahkan -l
operan akan mencakup detail pid.