![防止显示“[1] + did $scriptname”和“[1] 31303”](https://linux22.com/image/96518/%E9%98%B2%E6%AD%A2%E6%98%BE%E7%A4%BA%E2%80%9C%5B1%5D%20%2B%20did%20%24scriptname%E2%80%9D%E5%92%8C%E2%80%9C%5B1%5D%2031303%E2%80%9D.png)
我为我的杂种狗设置了一个别名:alias mutt='$HOME/.mutt/run-notmuch-offlineimap & ; mutt'
。
笔记:将我的别名更改为alias mutt='$HOME/.mutt/run-notmuch-offlineimap 2> /dev/null & ; mutt'
或 会alias mutt='$HOME/.mutt/run-notmuch-offlineimap 2>&1 >/dev/null & ; mutt'
产生完全相同的结果。
该脚本run-notmuch-offlineimap
看起来像这样:
#!/usr/bin/env zsh
notmuch="$(which notmuch)"
$notmuch new --quiet
$notmuch tag +inbox -- "folder:dev/dev|INBOX or folder:pers/pers|INBOX"
$notmuch tag +sent -- "folder:dev/dev|Sent or folder:pers/pers|Sent"
$notmuch tag +drafts -- "folder:dev/dev|Drafts or folder:pers/pers|Sent"
$notmuch tag +github -- "folder:dev/dev|github and not tag:github"
# test if the offlineimap instance of account dev is already running
if [[ $(pgrep -f 'offlineimap.*dev.*') == "" ]]
then
offlineimap -c "$HOME/.fetch-send-mail/dev/dev.imap" -u quiet
fi
# test if the offlineimap instance of account dev is already running
if [[ $(pgrep -f 'offlineimap.*pers.*') == "" ]]
then
offlineimap -c "$HOME/.fetch-send-mail/pers/pers.imap" -u quiet
fi
(如果我在此脚本中使用 bash,结果将完全相同)
当我开始 mutt 时,会发生以下情况:
~
$ mutt
[1] 31303
Mailbox is unchanged.
# some seconds afterwards:
~
$
[1] + done $HOME/.mutt/run-notmuch-offlineimap
~
消息“邮箱未更改”来自 mutt 本身,因此这是预期的。但是,我可以阻止[1]
显示消息吗?例如,当我执行 mutt 时,它应该只打印此内容(而不打印其他内容):
~
$ mutt
Mailbox is unchanged.
~
$
我怎样才能做到这一点?
答案1
如果您在 zsh 中,则可以更改别名来启动后台进程,而&!
不仅仅是&
.这将立即否认的过程。
alias mutt='$HOME/.mutt/run-notmuch-offlineimap &! mutt'
如果您在 bash 中,那么您可以disown
在命令后使用来获得类似的效果,但您仍然会收到列出 pid 的第一个作业控制消息。
alias mutt='$HOME/.mutt/run-notmuch-offlineimap & disown; mutt'
您可以通过使用子 shell 来避免这两种情况:
alias mutt='($HOME/.mutt/run-notmuch-offlineimap &); mutt'
答案2
解释
[1] + done <scriptname> ... [1] 31303
由 shell (zsh)打印作业控制。这是使用 异步运行命令的结果&
。
在您的情况下,mutt
是别名$HOME/.mutt/run-notmuch-offlineimap & ; mutt
,因此run-notmuch-offlineimap
是异步执行的,并且在启动和完成时将打印作业控制消息。
例子:
$ { sleep .3; echo; } &
[1] 71975
$
[1] + 71975 done { sleep .3; echo; }
可能的解决方案
取消设置MONITOR
shell 选项
$ unsetopt MONITOR # or set +m
$ { sleep .3; echo; } &
# (no job control messages)
# reset the option:
$ setopt MONITOR # or set -m
这将抑制作业控制消息。另请注意,该作业不会添加到作业表 ( jobs
) 中。
从文档中:
- 选项,16.2.7 作业控制:
MONITOR (-m, ksh: -m) Allow job control. Set by default in interactive shells.
- 10.1 工作
If the MONITOR option is set, an interactive shell associates a job with each pipeline. It keeps a table of current jobs, printed by the jobs command, and assigns them small integer numbers. When a job is started asynchronously with ‘&’, the shell prints a line to standard error which looks like: [1] 1234
执行而&!
不是&
异步命令将立即被拒绝并从作业表中删除。
$ { sleep .3; echo; } &!
# (no job control messages)
在子 shell 中执行异步命令本身
$ ({ sleep .3; echo; } &)
# (no job control messages)
(上面说明了这一点,但是异步运行没有多大意义,{..}
因为(..)
(子 shell 本身)不是异步运行的。因此完整的命令将被阻止。)
但为什么在子 shell 中执行异步命令是否会抑制作业控制输出?因为:MONITOR
子 shell 中未设置 shell 选项(无论父 shell 中的设置如何):
$ setopt monitor;
$ [[ -o monitor ]] && echo "SET" || echo "UNSET"
SET
$ ( [[ -o monitor ]] && echo "SET" || echo "UNSET" )
UNSET
其他选项