通过进程名称检查 Mac 进程是否正在使用 Bash 运行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1821886/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Check if Mac process is running using Bash by process name
提问by Chris Redford
How do you check if a process on Mac OS X is running using the process's name in a Bash script?
如何使用 Bash 脚本中的进程名称检查 Mac OS X 上的进程是否正在运行?
I am trying to write a Bash script that will restart a process if it has stopped but do nothing if it is still running.
我正在尝试编写一个 Bash 脚本,如果它已经停止,它将重新启动一个进程,但如果它仍在运行,则什么都不做。
回答by Jed Smith
Parsing this:
解析这个:
ps aux | grep -v grep | grep -c [-i] $ProcessName
...is probably your best bet.
...可能是你最好的选择。
ps aux
lists all the currently running processes including the Bash script itself which is parsed out by grep -v grep
with advice from Jacob (in comments) and grep -c [-i] $ProcessName
returns the optionally case-insensitive integer number of processes with integer return suggested by Sebastian.
ps aux
列出所有当前正在运行的进程,包括 Bash 脚本本身,该脚本本身grep -v grep
由 Jacob 的建议(在注释中)解析,并grep -c [-i] $ProcessName
返回可选的不区分大小写的整数进程,并返回 Sebastian 建议的整数。
Here's a short script that does what you're after:
这是一个简短的脚本,可以完成您的任务:
#!/bin/bash
PROCESS=myapp
number=$(ps aux | grep -v grep | grep -ci $ProcessName)
if [ $number -gt 0 ]
then
echo Running;
fi
EDIT:I initially included a -i
flag to grep
to make it case insensitive; I did this because the example program I tried was python
, which on Mac OS X runs as Python
-- if you know your application's case exactly, the -i
is not necessary.
编辑:我最初包含一个-i
标志grep
以使其不区分大小写;我这样做是因为我尝试的示例程序是python
,它在 Mac OS X 上的运行方式是Python
——如果您确切地了解应用程序的情况,-i
则不需要。
The advantage of this approach is that it scales with you -- in the future, if you need to make sure, say, fiveinstances of your application are running, you're already counting. The only caveat is if another application has your program's name in its command line, it might come up -- regular expressions to grep
will resolve that issue, if you're crafty (and run into this).
这种方法的优点是它可以随您扩展——将来,如果您需要确保应用程序的五个实例正在运行,那么您已经在计数了。唯一需要注意的是,如果另一个应用程序在其命令行中包含您的程序名称,它可能会出现 -grep
如果您很狡猾(并遇到此问题),正则表达式将解决该问题。
回答by Nick Zalutskiy
A shorter solution:
更短的解决方案:
if pgrep $PROCESS_NAME; then
echo 'Running';
fi
Explanation:
解释:
pgrep
exits with 0 if there is a process matching $PROCESS_NAME
running, otherwise it exist with 1.if
checks the exit code of pgrep
, and, as far as exit codes go, 0 is success.
pgrep
如果有匹配$PROCESS_NAME
正在运行的进程,则以 0 退出,否则以 1 存在。if
检查 的退出代码pgrep
,并且就退出代码而言,0 表示成功。
回答by amrox
Another way is to use (abuse?) the -d
option of the killall
command. The -d
options won't actually kill the process, but instead print what will be done. It will also exit with status 0
if it finds a matching process, or 1
if it does not. Putting this together:
另一种方法是使用(滥用?)命令的-d
选项killall
。这些-d
选项实际上不会终止进程,而是打印将要执行的操作。0
如果找到匹配的进程,或者1
没有找到,它也会退出并显示状态。把这个放在一起:
#!/bin/bash
`/usr/bin/killall -d "" &> /dev/null`
let "RUNNING = ! $?" # this simply does a boolean 'not' on the return code
echo $RUNNING
To give credit where its due, I originally pulled this technique from a script in the iTunes installer.
为了给予应有的信任,我最初从 iTunes 安装程序的脚本中提取了这项技术。
回答by Dan Gerrity
This simple command will do the trick. The brackets around the process name prevent the grep command from showing in the process list. Note there is no space after the comma. There may be some portability issues as pson some unix systems may require a dash before the options:
这个简单的命令可以解决问题。进程名称周围的括号可防止 grep 命令显示在进程列表中。注意逗号后没有空格。可能存在一些可移植性问题,因为某些 unix 系统上的ps可能需要在选项前加一个破折号:
ps axo pid,command | grep "[S]kype"
The advantage is that you can use the results in an if statement like this:'
优点是您可以在这样的 if 语句中使用结果:'
if [[ ! $(ps axo pid,command | grep "[i]Tunes.app") ]]; then
open -a iTunes
fi
Or if you prefer this style:
或者,如果您更喜欢这种风格:
[[ ! $(ps axo pid,command | grep "[S]kype") ]] && open -a Skype || echo "Skype is up"
Another advantage is that you can get the pid by adding a pipe to awk '{print $1}'.
另一个优点是您可以通过向 awk '{print $1}' 添加管道来获取 pid。
echo "iTunes pid: $(ps axo pid,command | grep "[i]Tunes.app" | awk '{print }')"
回答by Markizano
You can use either killall or kill, depending on if you are trying to find the task by PID or by name.
您可以使用 killall 或 kill,具体取决于您是尝试按 PID 还是按名称查找任务。
By Name:
按名字:
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 if ! kill -0 $PID 2>/dev/null; then
# Restart app, do the needful.
else
at -f 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
+30seconds
fi
+30seconds # If you don't have this on cron, you can use /usr/bin/at
fi
By PID:
通过PID:
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 }'`
echo "it's PID is $PID"
fi
If you look at the OSX Manualyou will see a different set of process management commands; since it's not the linux kernel, it makes sense that they would manage processes differently.
如果您查看OSX 手册,您会看到一组不同的进程管理命令;因为它不是 linux 内核,所以它们以不同的方式管理进程是有道理的。
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/killall.1.html
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/killall.1.html
A sample output from my terminal (striking out the user and hostname, of course):
我的终端的示例输出(当然,删除用户和主机名):
#!/bin/sh
ps axc |awk "BEGIN{ n=tolower(\"\")}\
tolower($5) ~n {print $1}";
The return code from a kill -0 will always result in a safe way to check if the process is running, because -0 sends no signal that will ever be handled by an application. It won't kill the application, and "kill" is only called "kill" because it's usually used to stop an application.
kill -0 的返回码将始终以一种安全的方式检查进程是否正在运行,因为 -0 不会发送任何应用程序处理的信号。它不会杀死应用程序,“kill”仅称为“kill”,因为它通常用于停止应用程序。
When you look at the interfaces it uses in the source, you'll see that it's actually interacting with the process table directly (and not grepping a potentially loaded output from ps), and just sending a signal to an application. Some signals indicate the application should shutdown or stop, while other signals tell it to restart services, or re-read configuration, or re-open file descriptors to log files that have been recently rotated. There are a plethora of things that "kill" and "killall" can do that doesn't terminate the application, and it's used regularly to simply send a signal to the application.
当您查看它在源代码中使用的接口时,您会发现它实际上是直接与进程表交互(而不是从 ps 获取潜在加载的输出),并且只是向应用程序发送信号。一些信号表明应用程序应该关闭或停止,而其他信号则告诉它重新启动服务,或重新读取配置,或重新打开文件描述符以记录最近轮换的文件。有很多“kill”和“killall”可以做的事情不会终止应用程序,并且它经常用于简单地向应用程序发送信号。
回答by Ingmar Hupp
I lack the reputation to comment on the killall answer above, but there's killall -s
for doing it without sending any signals:
我缺乏评论上述 killall 答案的声誉,但killall -s
这样做是为了不发送任何信号:
echo $PATH
回答by Zontar Ian
I've extended a pidof script found on the net to use regular expressions (usually substrings) and be case insensitive
我已经扩展了在网上找到的 pidof 脚本以使用正则表达式(通常是子字符串)并且不区分大小写
chmod 755 /usr/local/bin/pidof
just create a script named "pidof" with this content, and put it in you path, i.e. in one of the dirs in
只需使用此内容创建一个名为“pidof”的脚本,并将其放在您的路径中,即在其中的一个目录中
kill -9 `pidof pyth`
and make it executable (maybe using sudo)
并使其可执行(可能使用sudo)
if pidof $processname >/dev/null ; then echo $processname is running ; fi
and use it like this, of course
并像这样使用它,当然
killall -d TextEdit &> /dev/null && killall TextEdit &> /dev/null; open -a TextEdit
回答by matja
does Mac have pidof? ...
Mac有pidof吗?...
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
回答by kusai
It has for sure!
它肯定有!
pgrep, pkill and pfind for OpenBSD and Darwin (Mac OS X)
用于 OpenBSD 和 Darwin (Mac OS X) 的 pgrep、pkill 和 pfind
http://proctools.sourceforge.net
http://proctools.sourceforge.net
(also available via MacPorts: port info proctools )
(也可通过 MacPorts 获得:端口信息 proctools )
pidof by nightproductions.net
pidof by nightproductions.net
回答by Neville Hillyer
Perhaps too late for the OP but this may help others who find this thread.
对于 OP 来说可能为时已晚,但这可能会帮助找到此线程的其他人。
The following modification of the amrox theme above works well for restarting applications on my OS X:
上面 amrox 主题的以下修改适用于在我的 OS X 上重新启动应用程序:
##代码##I use the following AppleScript to update and restart daemons:
我使用以下 AppleScript 来更新和重启守护进程:
##代码##It assumes the original or updated plist file is in the same directory as the AppleScript.
它假定原始或更新的 plist 文件与 AppleScript 位于同一目录中。