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
    Oct 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
    Oct 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
    Oct 23, 2015 at 12:12
  • ps --version --> "procps-ng version 3.3.9"
    – will
    Oct 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
    Oct 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.. Apr 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. Apr 10, 2021 at 17:35
  • To immediately kill, use pkill that takes exactly the same arguments as pgrep. Jul 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
    Oct 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
    Oct 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
    Oct 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
    Oct 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
    Oct 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
    May 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.

Not the answer you're looking for? Browse other questions tagged .