Linux 如何获取使用 sudo 运行的命令的 pid

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9315829/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:37:09  来源:igfitidea点击:

How to get the pid of command running with sudo

linuxbashshellunixsudo

提问by user87005

I am trying to get the pid of this command.

我正在尝试获取此命令的 pid。

sudo -b tcpdump -i eth0 port 80 -w eth0.pcap

采纳答案by matchew

for this purpose I will enter

为此,我将进入

sudo gvim &

sudo gvim &

ps aux | grep gvim

ps aux | grep gvim

supplies me with the following output

为我提供以下输出

root 11803 0.0 0.0 12064 2776 pts/3 T 12:17 0:00 sudo gvim

root 11803 0.0 0.0 12064 2776 pts/3 T 12:17 0:00 sudo gvim

to grab only the pID i prefer to use awk

只获取 pID 我更喜欢使用 awk

ps aux | awk '/gvim/ {print $2}'

ps aux | awk '/gvim/ {print $2}'

which would return simply

这将简单地返回

11803

11803

I could kill the program from awkas well by piping a kill command to bash

我也可以awk通过将 kill 命令传递给 bash 来终止程序

ps aux | awk '/gvim/ {print "sudo kill -9 "$2}' | bash

ps aux | awk '/gvim/ {print "sudo kill -9 "$2}' | bash

回答by Chris Dodd

You can use $!to get the pid of the last background process (which will be the sudo in this case), and ps --ppidto find out about its children. So for example:

您可以使用$!获取最后一个后台进程的 pid(在本例中为 sudo),并ps --ppid了解其子进程。例如:

$ sudo tcpdump -i eth0 port 80 -w eth0.pcap &
$ ps --ppid $! -o pid=
16772
$ ps --pid 16772
  PID TTY          TIME CMD
16772 pts/3    00:00:00 tcpdump

If you're doing this in a script, you might want to use a sleep 1between the sudoand psto ensure that the child gets started.

如果您在脚本中执行此操作,您可能希望sleep 1sudo和之间使用 aps以确保子项开始。

Note that if you really must use the -bflag to sudo, this won't work, as that will cause sudo to do an extra fork and immediately exit, losing the connection between child and parent (the tcpdump command will get reparented to init), which means you'll have no easy way of distinguishing the child from any other similar command.

请注意,如果您确实必须使用-b标志来执行 sudo,这将不起作用,因为这将导致 sudo 执行额外的分叉并立即退出,从而失去子级和父级之间的连接(tcpdump 命令将重新分配给 init),这意味着您将没有简单的方法将子命令与任何其他类似命令区分开来。

回答by Christopher Neylan

The -ooption to pslets you choose what fields to display. Of those fields, you can show things like cumulative cpu time (cputime), elapsed time (etime), and start time (lstart). You can also sort on a field using --sort. So a solution for you could be:

-o选项可ps让您选择要显示的字段。在这些字段中,您可以显示累积 CPU 时间 ( cputime)、经过时间 ( etime) 和开始时间 ( lstart) 等内容。您还可以使用 对字段进行排序--sort。因此,您的解决方案可能是:

ps -eo pid,command,lstart --sort lstart | grep 'sudo -b tcpdump' | tail -1

You don't even need to tell psto display the field you want to sort by. man psfor more details.

您甚至不需要告诉ps显示要作为排序依据的字段。 man ps更多细节。

回答by user2690301

Here's one way to do it:

这是一种方法:

sudo -u username sh -c "echo $$ > /tmp/my_pid/file; exec my_command" &

The other answers here rely on grepping ps output. If there's multiple tcpdump commands running, you may accidentally grep the wrong pid. This gets the actual pid and puts it in a file.

这里的其他答案依赖于 grepping ps 输出。如果有多个 tcpdump 命令正在运行,您可能会不小心 grep 错误的 pid。这将获取实际的 pid 并将其放入文件中。

Here's an example running tcpdump as root:

这是一个以 root 身份运行 tcpdump 的示例:

 $ sudo -u root sh -c "echo $$ > /tmp/tcpdump.pid; exec tcpdump -i en3 -w eth0.pcap" &
[1] 37201
tcpdump: listening on en3, link-type EN10MB (Ethernet), capture size 65535 bytes
$ sudo kill `cat /tmp/tcpdump.pid`
6212 packets captured
6243 packets received by filter
0 packets dropped by kernel
[1]+  Done                    sudo -u root sh -c "echo $$ > /tmp/tcpdump.pid; exec tcpdump -i en3 -w eth0.pcap"
$