40

Is there any way to set the process name of a shell script? This is needed for killing this script with the killall command.

Nakilon
  • 33,683
  • 14
  • 104
  • 137
dan
  • 1,007
  • 3
  • 11
  • 17

11 Answers11

30

Here's a way to do it, it is a hack/workaround but it works pretty good. Feel free to tweak it to your needs, it certainly needs some checks on the symbolic link creation or using a tmp folder to avoid possible race conditions (if they are problematic in your case).

Demonstration

wrapper

#!/bin/bash
script="./dummy"
newname="./killme"

rm -iv "$newname"

ln -s "$script" "$newname"

exec "$newname" "$@"

dummy

#!/bin/bash
echo "I am $0"
echo "my params: $@"

ps aux | grep bash

echo "sleeping 10s... Kill me!"
sleep 10

Test it using:

chmod +x dummy wrapper
./wrapper some params

In another terminal, kill it using:

killall killme

Notes

Make sure you can write in your current folder (current working directory).

If your current command is:

/path/to/file -q --params somefile1 somefile2

Set the script variable in wrapper to /path/to/file (instead of ./dummy) and call wrapper like this:

./wrapper -q --params somefile1 somefile2
Weboide
  • 1,082
  • 1
  • 11
  • 21
  • This does not appear to change the actual process name as reflected by `/proc/$PID/comm` but rather changes the command as displayed in `ps` and `top` – Xaser Jan 07 '22 at 17:52
3

You cannot do this reliably and portably, as far as I know. On some flavors of Unix, changing what's in argv[0] will do the job. I don't believe there's a way to do that in most shells, though.

Here are some references on the topic.

joar
  • 13,627
  • 1
  • 27
  • 52
Brian Clapper
  • 24,425
  • 7
  • 63
  • 65
3

You can use the kill command on a PID so what you can do is run something in the background, get its ID and kill it

PID of last job run in background can be obtained using $!.

echo test & echo $!

Abs
  • 53,696
  • 97
  • 268
  • 401
2

You can all use the -f flag to pgrep/pkill which will search the entire command line rather than just the process name. E.g.

./script &
pkill -f script
sheridp
  • 1,296
  • 1
  • 10
  • 23
  • Thanks! I've been looking to rename what shows in the `CMD` column of `ps -u username` just so I can kill the appropriate process easier. But searching and killing via `pkill -f myscript.py` is much more convenient. – sc4s2cg Dec 05 '20 at 15:53
1

This is an extremely old post. Pretty sure the original poster got his/her answer long ago. But for newcomers, thought I'd explain my own experience (after playing with bash for a half hour). If you start a script by script name w/ something like:

./script.sh

the process name listed by ps will be "bash" (on my system). However if you start a script by calling bash directly:

/bin/bash script.sh /bin/sh script.sh bash script.sh

you will end up with a process name that contains the name of the script. e.g.:

/bin/bash script.sh

results in a process name of the same name. This can be used to mark pids with a specific script name. And, this can be useful to (for example) use the kill command to stop all processes (by pid) that have a process name containing said script name.

0

On Linux at least, killall dvb works even though dvb is a shell script labelled with #!. The only trick is to make the script executable and invoke it by name, e.g.,

dvb watch abc write game7 from 9pm for 3:30

Running ps shows a process named

/usr/bin/lua5.1 dvb watch ...

but killall dvb takes it down.

Norman Ramsey
  • 193,779
  • 59
  • 352
  • 532
0

%1, %2... also do an adequate job:

#!/bin/bash
# set -ex

sleep 101 &
FIRSTPID=$!
sleep 102 &
SECONDPID=$!

echo $(ps ax|grep "^\(${FIRSTPID}\|${SECONDPID}\) ")
kill %2
echo $(ps ax|grep "^\(${FIRSTPID}\|${SECONDPID}\) ")
sleep 1
kill %1
echo $(ps ax|grep "^\(${FIRSTPID}\|${SECONDPID}\) ")
slaxor
  • 521
  • 4
  • 8
0

Include #![path to shell]

Example for path to shell -

  1. /usr/bin/bash
  2. /bin/bash
  3. /bin/sh

Full example

#!/usr/bin/bash
Executer
  • 1
  • 1
0

I put these two lines at the start of my scripts so I do not have to retype the script name each time I revise the script. It won't take $0 of you put it after the first shebang. Maybe someone who actually knows can correct me but I believe this is because the script hasn't started until the second line so $0 doesn't exist until then:

#!/bin/bash 
#!/bin/bash ./$0

This should do it.

unifex
  • 155
  • 1
  • 6
-1

Erm... unless I'm misunderstanding the question, the name of a shell script is whatever you've named the file. If your script is named foo then killall foo will kill it.

VoteyDisciple
  • 36,263
  • 5
  • 90
  • 93
  • 5
    Not true. Try it. Create a file called "tst.sh", make it executable, have it do something like a "sleep 30", and fire it up. You'll note that the process name associated with it is "/bin/sh" or "/bin/bash" or whatever you put in the shebang line. – Brian Clapper Jun 19 '10 at 14:06
-1

We won't be able to find pid of the shell script using "ps -ef | grep {scriptName}" unless the name of script is overridden using shebang. Although all the running shell scripts come in response of "ps -ef | grep bash". But this will become trickier to identify the running process as there will be multiple bash processing running simultaneously.

So a better approach is to give an appropriate name to the shell script.

Edit the shell script file and use shebang (the very first line) to name the process e.g. #!/bin/bash /scriptName.sh

In this way we would be able to grep the process id of scriptName using

"ps -ef | grep {scriptName}"
MangeshBiradar
  • 3,572
  • 1
  • 22
  • 38