您好,我在运行 watch 命令时遇到问题,如下所示:
watch cat /proc/$(ps ax | grep processname | grep -v grep | awk '{print $1}')/status
该命令在我启动时起作用。但是,然后我重新启动正在监视的进程,watch 命令仍然使用旧的进程 ID。我希望它刷新进程 ID 并显示同名新进程的状态。该部分$(ps ax | grep processname | grep -v grep | awk '{print $1}')
显然只在开始时运行。如何在每次手表刷新输出时重新评估它?
我不想将 cat 命令放入 bash 脚本中并从 watch 运行该脚本。
答案1
这不是一个简洁的方法,但如果您真的不愿意创建脚本。你可以试试eval
。
watch eval 'cat /proc/$(ps ax | grep processname | grep -v grep | awk '"'"'{print $1}'"'"')/status'
答案2
将以下内容保存ps-status.sh
到 $PATH 中的某个位置,并使用以下命令使其可执行chmod +x
:
#!/bin/sh
[ -z "$1" ] && echo "process name required" && exit 1
pid="$(pgrep -f "$1")"
[ -z "$pid" ] && echo "no such process: $1" && exit 1
countpids="$(echo "$pid" | wc -l)"
[ "$countpids" -gt 1 ] && "Warning: more than one pid matches $1" && exit 1
cat "/proc/$pid/status"
watch
然后像这样运行:
watch ps-status.sh processname
$pid
可能应该是一个数组,但这需要 bash 而不仅仅是 sh:
#!/bin/bash
[ -z "$1" ] && echo "process name required" && exit 1
pids=( $(pgrep -f "$1") )
[ "${#pids[@]}" -eq 0 ] && echo "no such process: $1" && exit 1
[ "${#pids[@]}" -gt 1 ] && echo "Warning: more than one pid matches $1"
# display first matching PID, even if there were more than 1 matching.
cat "/proc/${#pids[0]}/status"
答案3
脚本文件
#!/bin/bash
ps -eaf | grep -i processname| grep -v grep |awk '{print $2}'
/etc/init.d/servicename restart
解释
安排 crontab 每 1 分钟执行一次
然后使用下面的watch命令查看进程名重启后进程id的差异
watch -n 60 script.sh
答案4
您可以只用单引号$(...)
来防止它被运行该东西的交互式 shell 扩展。然后你必须通过暂时切换到双引号并返回来转义其中的单引号。所以以下工作:
watch cat /proc/'$(ps ax | grep processname | grep -v grep | awk '"'"'{print $1}'"'"')'/status
然而,为了理解watch
这里和一般情况下正在做什么,您必须记住,watch
首先将所有非标志参数连接到一个命令字符串中。它这样做是为了“有帮助”,但我认为这实际上适得其反,因为它掩盖了正在发生的事情。我认为,如果您始终只给它一个命令字符串(在本例中用单引号引起来,以防止交互式 shell 扩展其中的任何内容),那么它会更清晰、更容易理解:
watch 'cat /proc/$(ps ax | grep processname | grep -v grep | awk '"'"'{print $1}'"'"')/status'