Is there any way to set the process name of a shell script? This is needed for killing this script with the killall command.
13 Answers
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

- 1,112
- 1
- 11
- 22
-
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
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.

- 15,077
- 1
- 29
- 54

- 25,705
- 7
- 65
- 65
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 $!

- 56,052
- 101
- 275
- 409
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.

- 31
- 1
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

- 1,386
- 1
- 11
- 24
-
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
Include #![path to shell]
Example for path to shell -
- /usr/bin/bash
- /bin/bash
- /bin/sh
Full example
#!/usr/bin/bash

- 11
- 2
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.

- 198,648
- 61
- 360
- 533
%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}\) ")

- 531
- 4
- 8
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.

- 165
- 1
- 6
My solution uses a trivial python script, and the setproctitle package. For what it's worth:
#!/usr/bin/env python3
from sys import argv
from setproctitle import setproctitle
from subprocess import run
setproctitle(argv[1])
run(argv[2:])
Call it e.g. run-with-title
and stick it in your path somewhere. Then use via
run-with-title <desired-title> <script-name> [<arg>...]

- 1,072
- 8
- 9
Run bash
script with explicit call to bash
(not just like ./test.sh
). Process name will contain script in this case and can be found by script name. Or by explicit call to bash
with full path as
suggested in display_name_11011's answer:
bash test.sh # explicit bash mentioning
/bin/bash test.sh # or with full path to bash
ps aux | grep test.sh | grep -v grep # searching PID by script name
If the first line in script (test.sh) explicitly specifies interpreter:
#!/bin/bash
echo 'test script'
then it can be called without explicit bash
mentioning to create process with name '/bin/bash test.sh':
./test.sh
ps aux | grep test.sh | grep -v grep
Also as dirty workaround it is possible to copy and use bash with custom name:
sudo cp /usr/bin/bash /usr/bin/bash_with_other_name
/usr/bin/bash_with_other_name test.sh
ps aux | grep bash_with_other_name | grep -v grep

- 542
- 1
- 6
- 15
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.

- 37,319
- 5
- 97
- 97
-
6Not 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
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}"

- 3,820
- 1
- 23
- 41

- 43
- 8