我知道您可以使用它在后台启动一个进程,而无需在该进程放入后台以及完成时收到通知,如下所示:
(命令 &) &> /dev/null
但是,这会删除进程完成时捕获的选项 ( trap child_done CHLD
)。
我怎样才能两者兼得?
答案1
任务假脱机程序可能对你有帮助。
如在鲜肉网:
任务假脱机程序是一种 Unix 批处理系统,其中假脱机的任务一个接一个地运行。可以随时设置一次运行的作业量。每个系统中的每个用户都有自己的作业队列。这些任务在任何 shell/进程的正确上下文(入队上下文)中运行,并且可以轻松观看其输出/结果。当您知道您的命令依赖于大量 RAM、大量磁盘使用、提供大量输出,或者出于某种原因最好不要同时运行所有命令,而您想保留这些命令时,它非常有用。您的资源忙于实现最大效益。它的界面允许在脚本中轻松使用它。
任务后台处理程序可用于德班、Ubuntu 和其他发行版。
它允许您运行一个任务队列,并根据需要访问它们的输出。
例如:
$ tsp sleep 5
0
$ tsp sleep 5
1
$ tsp
ID State Output E-Level Times(r/u/s) Command [run=1/1]
2 running /tmp/ts-out.ZWn6Le sleep 5
1 finished /tmp/ts-out.Fhlcle 0 5.00/0.00/0.01 sleep 5
如果你在后台运行很多作业,它肯定会对你有帮助。
您可以按顺序运行它们,也可以在预设数量的槽中运行它们。您还可以在任务之间建立依赖关系(运行任务1除非任务0成功完成)。
答案2
以下是在两者中执行此操作的方法{ba,z}sh
。
使用函数有助于不需要通过使用来保存和恢复变量zsh
的状态。monitor
setopt local_options
# Run the command given by "$@" in the background
silent_background() {
if [[ -n $ZSH_VERSION ]]; then # zsh: https://superuser.com/a/1285272/365890
setopt local_options no_notify no_monitor
"$@" &
elif [[ -n $BASH_VERSION ]]; then # bash: https://stackoverflow.com/a/27340076/5353461
{ 2>&3 "$@"& } 3>&2 2>/dev/null
else # Unknownness - just background it
"$@" &
fi
}
使用方法如下:
trap 'echo child done' CHLD
silent_background sleep 1
将产生预期的child done
消息。
答案3
命令输出的重定向似乎无关紧要,因为通知已发送通过外壳当一个工作是异步启动的。更准确地说,它是与以下内容相关的 shell 功能(功能性)作业控制。
这里引用来自“Bash 参考手册”,“作业控制”一章,第一节的内容。
shell 将一个作业与每个管道关联起来。它保存当前正在执行的作业的表,可以使用
jobs
命令列出该表。当 Bash 异步启动作业时,它会打印如下行:[1] 25647
表示该作业的作业号为 1,并且与该作业关联的管道中最后一个进程的进程 ID 为 25647。单个管道中的所有进程都是同一作业的成员。 Bash 使用 JOB 抽象作为作业控制的基础。
请注意,shell 脚本不会显示此通知。
$ cat test
#!/bin/bash
true & echo true
$ ./test
true
据实
兹什
Zsh 文档提供了有关这些通知的类似指示,请参阅man 1 zshmisc
“JOBS”部分。当以下情况时,不会显示这些通知:作业控制被禁用。
监视器(-m,克什:-m)
允许作业控制。在交互式 shell 中默认设置。
zsh_prompt % setopt no_monitor
zsh_prompt % true & echo true
true
zsh_prompt %
zsh_prompt %
重击
看来 Bash 总是显示例如[1] 25647
。例如,“最终通知”[1]+ Done true
在以下情况下不会显示:作业控制被禁用。
bash_prompt $ true & echo true
[1] 25647
true
bash_prompt $
[1]+ Done true
作业控制已禁用
bash_prompt $ set +m # disable job control
bash_prompt $ true & echo true
[1] 25685
bash_prompt $
bash_prompt $
结论
不知道是否禁用作业控制隐藏通知是件好事吗?
资源
man 1 zshmisc
,工作部分。- Zsh,监视器:
man 1 zshoptions
。 - Bash 参考手册 - 作业控制
- Bash 参考手册 - 内置集
答案4
请参阅以下示例:
trap 'echo "DONE"' 0
{ find /usr & } &> /dev/null
wait
效果很好。不需要( )
:这会产生一个不需要的子外壳。{ }
只是分组命令。