我跑弓箭在我的 .zshrc 中。问题是,由于显示当前 IP,它有时会运行两秒钟。为了使它不那么引人注目,我把它放在后台,如下所示:
# .zshrc
archey &
# lots of foo
wait
这样,它可以获取 IP,同时在我的 zshrc 中完成许多其他工作。但现在 zsh 每次都会显示作业和进程 ID,并且 archey 已完成:
Last login: Mon Jul 10 11:12:07 on ttys002
[1] 40436
# archey output
[1] + done archey
~
❯
由于文档指出这将被发送到 stderr,我尝试使用 2>/dev/null,但没有成功。
我怎样才能删除这两行?
答案1
答案2
如果你不想使用子shell,你可以使用:
# 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
# We'd use &| to background and disown, but incompatible with bash, so:
"$@" &
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
disown &>/dev/null # Close STD{OUT,ERR} to prevent whine if job has already completed
}
然后:
silent_background archey # Or whatever command you want to background
答案3
这应该不需要额外的脚本文件:
tmpf=`mktemp`
{ archey ; echo 1 > "$tmpf" ; } &|
# foo
while [ ! -s "$tmpf" ] ; do sleep 0.1 ; done
rm "$tmpf"
unset tmpf
关键是&|
操作符。它在后台运行给定的命令,但该命令不是作业,因此您的显示不会被垃圾邮件淹没。您无法使用wait
。我使用了一个临时文件来检测是否archey
已完成。
如果你# foo
也生成输出,则可能会遇到竞争条件。在这种情况下,将archey
输出捕获到另一个临时文件(如在另一个答案中) 并将其打印在末尾。
我不建议使用单个临时文件进行archey
输出和触发器。我认为,如果你这样做,当仍然写入文件时,while
测试可能会返回 true 。archey
答案4
这两行是 shell 的输出stderr
,而不是进程的输出。您无法让它们从 zsh 中消失。
从评论中意识到,您想要看到显示的输出,您需要执行三个步骤:
- 为了避免在后台启动 archey 的噪音,您必须从脚本启动它
- 要将 archey 的结果传回主脚本,您必须使用临时文件或类似的东西
- 要理解,当它完成时,你不能使用,
wait
因为它取决于嘈杂的背景开始
wrap-archey.sh:
#/bin/sh
archey >"$1" 2>&1
rm "$2"
启动-archey.sh:
/path/to/wrap-archey.sh "$1" "$2" >/dev/null 2>&1 &
.zshrc:
ARCHEYOUT=$(mktemp)
ARCHEYFLAG=$(mktemp)
/path/to/start-archey.sh "$ARCHEYOUT" "$ARCHEYFLAG" >/dev/null 2>&1
#
# lots of foo
#
while test -f "$ARCHEYFLAG"; do sleep 0.1 ; done
cat "$ARCHEYOUT"
rm "$ARCHEYOUT"
wrap-archey.sh 将把输出重定向到临时文件,完成后删除标志文件。这对于后台通信是必需的。
start-archey.sh 将在后台启动 wrap-archey.sh,消除主脚本中的噪音并立即返回。
.zshrc 将设置 flagfile 和 resultfile,在后台静默运行 start-archey.sh,然后执行 foo,然后通过轮询 flagfile 等待 archey 完成。然后清理。