( 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
)
该Shell将运行您的脚本并返回到交互式提示-只要您避免exit
从脚本中访问该Shell,即避免后台运行进程-即可将您的I / O链接到/dev/null.
演示:
% 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
我认为您应该对Shell的内置任务管理选项有所了解。@Kiwy和@jillagre都已经在他们的答案中提到了这一点,但可能需要进一步详细说明。而且,我已经提到了内置的一个POSIX指定的特殊shell,但是set, jobs, fg,
还有bg
更多,并且,正如另一个答案所示trap
,kill
还有另外两个。
如果尚未收到有关并发运行的后台进程状态的即时通知,那是因为您当前的shell选项设置为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
。我曾经读过一篇很有启发性的文章,将该过程比作道格拉斯·亚当斯(Douglas Adams)对行星NowWhat的描述:
“在《银河系漫游指南》中,道格拉斯·亚当斯提到了一个极其沉闷的星球,其中居住着一群沮丧的人类和某些带有锋利牙齿的动物,它们通过在大腿上用力地咬人与人类进行交流。这是惊人的。与UNIX类似,在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
给当前的前台进程组负责人,这很可能是您的shell,并且默认情况下还应将其配置trap
为该信号并挂起您的最后一条命令。再次,正如@jillagre和@Kiwy的答案一起显示的那样,并没有阻止您根据自己的喜好定制此功能。
SCREEN JOBS
因此,要利用这些功能,期望您首先了解它们并根据自己的需要自定义它们的处理方式。例如,我刚刚在Github上找到了这个screenrc,其中包含以下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详细信息。