16

I have two scripts:

  • running_script
  • script_one

I need to get the PID for the/any instances of running_script running under a username, and then pkill to stop the running_script and daughter processes.

We expected something like:

ps -fu will | grep running_script 

to find the running_script process(es). However checking the PID against the ps command output show that the cmd as: "bin/bash" for the running_script process.

running_script runs as a detached process(& operator) which starts script_one. I print the PID-s at the start to compare with ps command's output.

running_script & echo $! -- $BASHPID 

In the real use-case, we won't have PIDs for some running_script processes running. Also, script_one may or may not be a detached process from the running_script parent.

For the purposes of the exercise, script_one just does loops.

while [ true ] do echo " $0 - 35sec ..." sleep 35 done 

However that's just the example. The requirement is to get PID for the parent, running_script process(es).

Is there an option on ps or another command that can give me the name of the script file and the PID? Or a method to set a name that can be searched for?

In the final use-case, there could be several instances of running_script so picking them out by name seems the best option to date.

example

I thought it might help to show what the ps command shows, since most responses appear to think that's going to work. I ran this example just a while ago.

$ ./running_script & $ echo $! - $BASHPID 9047 - 3261 $ ps -ef | grep will UID PID PPID C STIME TTY TIME CMD will 8862 2823 0 22:48 ? 00:00:01 gnome-terminal will 8868 8862 0 22:48 ? 00:00:00 gnome-pty-helper will 8869 8862 0 22:48 pts/4 00:00:00 bash * will 9047 3261 0 22:55 pts/2 00:00:00 /bin/bash will 9049 9047 0 22:55 pts/2 00:00:00 /bin/bash will 9059 2886 0 22:56 pts/0 00:00:00 man pgrep will 9070 9059 0 22:56 pts/0 00:00:00 pager -s will 10228 9049 0 23:31 pts/2 00:00:00 sleep 35 will 10232 8869 0 23:31 pts/4 00:00:00 ps -ef will 10233 8869 0 23:31 pts/4 00:00:00 grep --colour=auto william 

I have marked PID #9047, is simply shows: - will 9047 3261 0 22:55 pts/2 00:00:00 /bin/bash

Is there something like a a "jobname" attribute I could set on linux?

4
  • Would it be enough to get the PID of the parent process of script1?
    – terdon
    CommentedOct 22, 2015 at 13:27
  • In the interest of saving some time, every ps option shows "bash/bash", NOT "running_script" when running_script is stared from the command line /terminal.
    – will
    CommentedOct 23, 2015 at 12:10
  • I'm testing these with v4.3.11(1)-release on linux mint 17. The requirement is for the PID of running_script. There is a (good) compliance reason for that requirement stemming from the hardware and software systems already running.
    – will
    CommentedOct 23, 2015 at 12:12
  • ps --version --> "procps-ng version 3.3.9"
    – will
    CommentedOct 25, 2015 at 4:44

4 Answers 4

26

Try pgrep -f running_script -- the -f option uses the whole command line to match against, not just the process name

4
  • The result is a null (or no output). That's on gnu bash: v4.3.11(1)-release
    – will
    CommentedOct 23, 2015 at 12:01
  • 1
    Add -l (--list-name) to pgrep to name those processes. E.g., for running script claws2postgres.sh, pgrep -l -f claws2postgres returns 23538 claws2postgres..CommentedApr 27, 2019 at 22:26
  • To immediately kill the found process use pgrep -f "searchterm" | xargs kill. Credits to user @cuonglm. Read his explanation here.
    – BoomZilla
    CommentedApr 10, 2021 at 17:35
  • To immediately kill, use pkill that takes exactly the same arguments as pgrep.CommentedJul 19, 2021 at 15:23
6

ps -o pid,args -C bash | awk '/running_script/ { print $1 }'

This uses ps to get the pid and args for all bash processes, then uses awk to print the pid (field 1) of the matching process.

BTW, ps -o pid,args -C bash gives you the pid and the name of the script file you asked for - the script's name is in the args of the bash command.

If you're going to use ps rather than pgrep at least use its full capabilities rather than the extraordinarily ugly ps ... | grep -v grep | grep | awk construct. The last grep isn't even needed as awk can perform the pattern match. In fact, neither of the greps are needed as awk can do it all: ps ax | awk '! /awk/ && /myprocessname/ { print $1}'

8
  • The result is a null (or no output), gnu bash: v4.3.11(1)-release. The output of the ps command is: 9047 /bin/bash 9049 /bin/bash, 8869 bash. I suppose PID 8869 is the parent (mother of all) bash processes. May be there's a different result if the running_script command is run from a script or something(??) rather than from the terminal (shell).
    – will
    CommentedOct 23, 2015 at 12:07
  • What version of ps are you running? Try ps --version. Both ps -ef and ps -o args are supposed to show the full command line, including arguments. And do you have any of the Environment Variables mentioned near the end of man ps set?
    – cas
    CommentedOct 23, 2015 at 21:52
  • I put version in the question: "procps-ng version 3.3.9". The mint system monitor shows the same information. It probably uses ps (too anyway). However the process pseudo device only shows bash/bash -- Which leads me to believe it is it is bash setting the command information.
    – will
    CommentedOct 25, 2015 at 4:49
  • yep, you're right. bash changes its args in ps. I'll try to find out if there's a way of getting ps to show the real args. In the meantime, you could try something like this if you are running on linux ps h -o pid -C bash | xargs -IXX grep -sEl 'running_script' /proc/XX/cmdline | sed -re 's:/proc/([^/]*)/.*:\1:'
    – cas
    CommentedOct 25, 2015 at 5:41
  • FYI, bash only changes its name in ps if you run the script as bash scriptname.sh. If you run it as just ./scriptname.sh (or /path/to/scriptname.sh) then the script's real name will appear in ps
    – cas
    CommentedOct 25, 2015 at 5:51
1
ps -ef | grep -v grep | grep <script_name> | awk '{print $2}' 

The above command will give the PID for the script_name. Also you can have the script write a temporary file with its running PID.

To save the current PID, add a line inside the script:

echo $$>/tmp/script_pid.tmp 
1
  • Maybe you mean ps -ef | grep -v grep | awk '/script_name/ {print $2}'. With pgrep you avoid the nasty grep -v grep
    – Pablo A
    CommentedMay 19, 2022 at 4:01
0
#!/bin/bash # pidofargs.sh # get process id by first argument of a process # using `ps -eo pid,args` and `read -a` # sample use: pidofargs.sh python /usr/bin/youtube-dl search_grep="$1" # first filter search_arg1="$2" # second filter # first filter ps -eo pid,args | grep "$search_grep" | while read pid args do read -a arg < <(echo "$args") # pid = process id # arg[0] = executable file of process # arg[1] = first argument of process # second filter if [[ "${arg[1]}" == "$search_arg1" ]] then # success echo $pid break fi done 

    You must log in to answer this question.

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.