( exec sh -i 3<<SCRIPT 4<&0 <&3 ⏎
echo "do this thing"
echo "do that thing"
exec 3>&- <&4
SCRIPT
)
Điều này được thực hiện tốt hơn từ một tập lệnh mặc dù với exec $0.
Hoặc nếu một trong những mô tả tệp đó hướng đến một thiết bị đầu cuối hiện không được sử dụng thì nó sẽ giúp - bạn cũng phải nhớ, các quy trình khác cũng muốn kiểm tra thiết bị đầu cuối đó.
Và nhân tiện, nếu mục tiêu của bạn là, như tôi nghĩ là, để bảo vệ môi trường của tập lệnh sau khi thực hiện nó, có lẽ bạn sẽ được phục vụ tốt hơn rất nhiều với:
. ./script
Vỏ .dot
và bash's source
không phải là một và giống nhau - vỏ .dot
là POSIX được chỉ định là vỏ được chế tạo đặc biệt và do đó gần như được bảo đảm như bạn có thể nhận được, mặc dù điều này không có nghĩa là đảm bảo nó sẽ ở đó ...
Mặc dù những điều trên nên làm như bạn mong đợi với ít vấn đề. Chẳng hạn, bạn có thể:
( exec sh -i 3<<SCRIPT 4<&0 <&3 ⏎
echo "do this thing"
echo "do that thing"
$(cat /path/to/script)
exec 3>&- <&4
SCRIPT
)
Trình bao sẽ chạy tập lệnh của bạn và đưa bạn trở lại dấu nhắc tương tác - miễn là bạn tránh exit
lấy trình bao từ tập lệnh của mình, nghĩa là hoặc làm nền cho quy trình của bạn - điều đó sẽ liên kết i / o của bạn với/dev/null.
BẢN GIỚI THIỆU:
% 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$
NHIỀU JOBS
Theo ý kiến của tôi, bạn nên làm quen một chút với các tùy chọn quản lý tác vụ tích hợp của shell. @Kiwy và @jillagre đều đã chạm vào điều này trong câu trả lời của họ, nhưng nó có thể đảm bảo thêm chi tiết. Và tôi đã đề cập đến một trình bao đặc biệt được tích hợp theo POSIX, nhưng set, jobs, fg,
và bg
một vài câu nữa, và, như một câu trả lời khác chứng minh trap
và kill
vẫn còn hai câu nữa.
Nếu bạn chưa nhận được thông báo tức thì về trạng thái của các quá trình chạy nền đồng thời, thì đó là vì các tùy chọn vỏ hiện tại của bạn được đặt thành mặc định do POSIX chỉ định -m
, nhưng set -b
thay vào đó bạn có thể nhận được các đồng bộ này một cách không đồng 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.
Một tính năng rất cơ bản của các hệ thống dựa trên Unix là phương pháp xử lý của chúng signals
. Có lần tôi đã đọc một bài viết khai sáng về chủ đề tương tự quá trình này với mô tả về hành tinh của Douglas Adams Bây giờ:
"Trong Hướng dẫn về thiên hà của Hitchhiker, Douglas Adams đã đề cập đến một hành tinh cực kỳ buồn tẻ, nơi sinh sống của một nhóm người bị trầm cảm và một giống động vật nào đó có hàm răng sắc nhọn giao tiếp với con người bằng cách cắn chúng rất mạnh vào đùi. tương tự như UNIX, trong đó hạt nhân giao tiếp với các quá trình bằng cách gửi tín hiệu tê liệt hoặc gây chết người cho chúng. Các quy trình có thể chặn một số tín hiệu và cố gắng thích ứng với tình huống, nhưng hầu hết chúng đều không. "
Đây là đề cập đến 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
Ít nhất là đối với tôi, trích dẫn ở trên đã trả lời rất nhiều câu hỏi. Chẳng hạn, tôi luôn coi nó rất lạ và hoàn toàn không trực quan rằng nếu tôi muốn theo dõi một dd
quá trình tôi phải thực hiện kill
. Sau khi đọc nó có ý nghĩa.
Tôi muốn nói rằng hầu hết trong số họ không cố gắng thích nghi vì lý do chính đáng - điều đó có thể gây phiền toái lớn hơn nhiều so với việc có một loạt các quy trình spam thiết bị đầu cuối của bạn với bất kỳ thông tin nào mà nhà phát triển của họ nghĩ là quan trọng đối với bạn .
Tùy thuộc vào cấu hình thiết bị đầu cuối của bạn (mà bạn có thể kiểm tra stty -a
) , CTRL+Z
có khả năng được đặt để chuyển tiếp SIGTSTP
đến người lãnh đạo nhóm quy trình tiền cảnh hiện tại, có khả năng là vỏ của bạn và cũng nên được cấu hình theo mặc định cho trap
tín hiệu đó và tạm dừng lệnh cuối cùng của bạn. Một lần nữa, như các câu trả lời của @jillagre và @Kiwy cùng hiển thị, không có gì ngăn cản bạn điều chỉnh chức năng này theo mục đích của bạn như bạn muốn.
SCREEN JOBS
Vì vậy, để tận dụng các tính năng này, trước tiên bạn cần hiểu chúng và tùy chỉnh xử lý chúng theo nhu cầu của riêng bạn. Ví dụ: tôi vừa tìm thấy screenrc này trên Github bao gồm screen
các ràng buộc khóa cho 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
Điều đó sẽ làm cho nó trở thành một vấn đề đơn giản để đình chỉ một quá trình đang chạy như một screen
quá trình con hoặc screen
chính quá trình con đó như bạn muốn.
Và ngay lập tức sau đó:
% fg
HOẶC LÀ:
% bg
Sẽ tiền cảnh hoặc nền quá trình như bạn muốn. Các jobs
built-in có thể cung cấp cho bạn một danh sách các bất cứ lúc nào. Thêm -l
toán hạng sẽ bao gồm chi tiết pid.