Macos 按进程名称使用Bash检查Mac进程是否正在运行

Macos 按进程名称使用Bash检查Mac进程是否正在运行,macos,bash,unix,process,Macos,Bash,Unix,Process,如何使用Bash脚本中的进程名称检查macosx上的进程是否正在运行 我正在尝试编写一个Bash脚本,如果进程已停止,它将重新启动进程,但如果进程仍在运行,则不执行任何操作。解析此脚本: ps aux | grep -v grep | grep -c [-i] $ProcessName …可能是你最好的选择 ps aux列出当前运行的所有进程,包括Bash脚本本身,该脚本由grep-v grep根据Jacob的建议(在注释中)解析出来,grep-c[-i]$ProcessName返回Sebas

如何使用Bash脚本中的进程名称检查macosx上的进程是否正在运行

我正在尝试编写一个Bash脚本,如果进程已停止,它将重新启动进程,但如果进程仍在运行,则不执行任何操作。

解析此脚本:

ps aux | grep -v grep | grep -c [-i] $ProcessName
…可能是你最好的选择

ps aux
列出当前运行的所有进程,包括Bash脚本本身,该脚本由
grep-v grep
根据Jacob的建议(在注释中)解析出来,
grep-c[-i]$ProcessName
返回Sebastian建议的可选不区分大小写的整数个进程

下面是一个简短的脚本,它完成了您的目标:

#!/bin/bash
PROCESS=myapp
number=$(ps aux | grep -v grep | grep -ci $PROCESS)

if [ $number -gt 0 ]
    then
        echo Running;
fi
编辑:我最初在
grep
中加入了一个
-I
标志,使其不区分大小写;我这样做是因为我尝试的示例程序是
python
,它在Mac OS X上作为
python
运行——如果您确切了解应用程序的情况,那么
-I
是不必要的

这种方法的优点是它可以随您的需要进行扩展——将来,如果您需要确保(比如)应用程序的五个实例正在运行,那么您已经在计算了。唯一需要注意的是,如果另一个应用程序的命令行中有您的程序名,它可能会出现--
grep
的正则表达式将解决这个问题,如果您很狡猾(并且遇到了这个问题)

研究Darwin手册页的和。

另一种方法是使用
killall
命令的
-d
选项(滥用?)。
-d
选项实际上不会终止进程,而是打印将要执行的操作。如果找到匹配的进程,它也将以状态
0
退出,如果没有,则以状态
1
退出。综合起来:

#!/bin/bash
`/usr/bin/killall -d "$1" &> /dev/null`
let "RUNNING = ! $?"     # this simply does a boolean 'not' on the return code
echo $RUNNING

为了证明这一点,我最初从iTunes安装程序中的一个脚本中提取了这项技术。

Mac有pidof吗

if pidof $processname >/dev/null ; then echo $processname is running ; fi
这是肯定的

用于OpenBSD和Darwin(Mac OS X)的pgrep、pkill和pfind

(也可通过MacPorts:port info proctools获得)


pidof by nightproductions.net

我没有声誉来评论上面的killall答案,但是有
killall-s
没有发出任何信号:

killall -s "$PROCESSNAME" &> /dev/null
if [ $? -eq 0 ]; then
    echo "$PROCESSNAME is running"
    # if you also need the PID:
    PID=`killall -s "$PROCESSNAME" | awk '{print $3}'`
    echo "it's PID is $PID"
fi

这个简单的命令就可以了。进程名称周围的括号阻止grep命令显示在进程列表中。注意逗号后没有空格。可能存在一些可移植性问题,因为在某些unix系统上,ps可能需要在选项之前加上破折号:

ps axo pid,command | grep "[S]kype"
这样做的好处是,您可以在如下if语句中使用结果:'

if [[ ! $(ps axo pid,command | grep "[i]Tunes.app") ]]; then
    open -a iTunes
fi
或者,如果您喜欢这种风格:

[[ ! $(ps axo pid,command | grep "[S]kype") ]] && open -a Skype  || echo "Skype is up"
另一个优点是,可以通过向awk“{print$1}”添加管道来获得pid

echo "iTunes pid: $(ps axo pid,command | grep "[i]Tunes.app" | awk '{print $1}')"

我已经扩展了网络上的一个pidof脚本,使用正则表达式(通常是子字符串)并且不区分大小写

#!/bin/sh
ps axc  |awk "BEGIN{ n=tolower(\"$1\")}\
    tolower(\$5) ~n {print  \$1}";
只需使用此内容创建一个名为“pidof”的脚本,并将其放在您的路径中,即在中的一个目录中

echo $PATH
并使其可执行(可能使用sudo)

当然,像这样使用它

kill -9 `pidof pyth`
较短的解决方案:

if pgrep $PROCESS_NAME; then
    echo 'Running';
fi
说明:

pgrep
如果有与
$process\u NAME
匹配的进程正在运行,则以0退出,否则以1退出。

if
检查
pgrep的退出代码,就退出代码而言,0是成功的。

对于OP来说可能太晚了,但这可能有助于找到此线程的其他人

上面对amrox主题的以下修改适用于在my OS X上重新启动应用程序:

killall -d TextEdit &> /dev/null && killall TextEdit &> /dev/null; open -a TextEdit
我使用以下AppleScript更新和重新启动守护程序:

tell application "System Events" to set pwd to POSIX path of container of (path to me)
do shell script "launchctl unload -w /Library/LaunchDaemons/time-test.plist; cp -f " & quoted form of pwd & "/time-test.plist /Library/LaunchDaemons; launchctl load -w /Library/LaunchDaemons/time-test.plist" with administrator privileges

它假定原始或更新的plist文件与AppleScript位于同一目录中。

您可以使用killall或kill,具体取决于您是尝试按PID还是按名称查找任务

姓名:

if ! killall -s -0 $PROCESS_NAME >/dev/null 2>&1; then
  # Restart failed app, or do whatever you need to prepare for starting the app.
else
  at -f $0 +30seconds # If you don't have this on cron, you can use /usr/bin/at
fi
通过PID:

if ! kill -0 $PID 2>/dev/null; then
  # Restart app, do the needful.
else
  at -f $0 +30seconds
fi
如果您查看OSX手册,您将看到一组不同的过程管理命令;因为它不是linux内核,所以它们可以用不同的方式管理进程

我的终端的一个示例输出(当然去掉了用户和主机名):

kill-0的返回代码总是以一种安全的方式检查进程是否正在运行,因为-0不会发送任何将由应用程序处理的信号。它不会终止应用程序,“kill”只被称为“kill”,因为它通常用于停止应用程序


当您查看它在源代码中使用的接口时,您将看到它实际上是直接与进程表交互的(而不是从ps中重新映射可能加载的输出),并且只是向应用程序发送一个信号。一些信号指示应用程序应该关闭或停止,而其他信号则指示应用程序重新启动服务,或重新读取配置,或重新打开文件描述符以记录最近旋转的文件。“kill”和“killall”可以做很多事情,但它们不会终止应用程序,并且经常用来向应用程序发送信号。

EWW。我不打算-1,因为我认为它只适用于不正确或不恰当的答案,但是哇。既然可以使用ps和grep,为什么还要这样做?特别是因为我非常确定使用ps和grep正是killall所做的……实际上killall比“ps | grep”聪明一点。如果你只是grep ps的输出,你可能会得到误报。人为的,但请将您的过程命名为“库”ps waux | grep Library“将匹配Mac上的许多内容。killall方法虽然有点古怪,但它只会匹配一个名为“Library”的实际进程。对不起,您使用的是什么系统?我在killall命令中没有看到-d选项@sobi3ch:讨论的是Mac OS X上缺少
pidof
,而不是Linux。
-d
选项由
man-ki记录
if ! kill -0 $PID 2>/dev/null; then
  # Restart app, do the needful.
else
  at -f $0 +30seconds
fi
user@localhost:~$ kill -0 782 # This was my old, stale SSH Agent.
bash: kill: (782) - No such process
user@localhost:~$ echo $?
1

user@localhost:~$ kill -0 813 # This is my new SSH agent, I only just created.
user@localhost:~$ echo $?
0