3

I have tried migrating the shebang for my bash scripts from #!/bin/bash to #!/usr/bin/env bash, and some of them were broken because they relied on this code that checks for existing instances of themselves runnning, and which works only with #!/bin/bash:

$ pidof -x myscript -o %PPID

What I would like to know is how can I reliably check if a script called by env is running, since most solutions I have tried will involve some dirty regex, and stilll end up being unreliable:

$ pgrep -f '(^|/)myscript(\s|$)'

Considering the path to my script is /home/user/myscript, the above code may return the PID for the following undesired commands:

editor /home/user/myscript
bash /tmp/myscript
bash /home/user/myscript with spaces
admirabilis
  • 4,712
  • For why one would change the interpreter line in the first place, see http://askubuntu.com/questions/88257/ and http://unix.stackexchange.com/questions/206350/ . – JdeBP Dec 30 '15 at 09:12

1 Answers1

2

On Linux, you could use pgrep to get PIDs of likely suspects, and inspect the first argument of those PIDs (available in /proc/$PID/cmdline). /proc/$PID/cmdline has all the arguments (including argument 0) of the process, separated ASCII NUL (\0).

Something like:

pgrep bash | xargs -I {} sed -nz '2{p; q}' /proc/{}/cmdline | grep -Fqzx "$0"

This assumes your sed and grep support null-separated lines. The sed prints the second line of the respective cmdline files (argument 1), which would be the script name. grep then looks for exact matches of your script name. You could do the entire match in sed, but I don't feel like juggling quotes.

This will fail if you call your script by different paths:

/home/user/myscript
cd /home; usr/myscript
myscript

However, it should be safe against whitespace in script names.

muru
  • 72,889
  • Hello, Happy New Year! What version of sed is this that supports null-separated new-lines? Mine doesn't: GNU sed 4.2.1. – admirabilis Jan 01 '16 at 11:27
  • @TeresaeJunior You too! mine is 4.2.2. – muru Jan 01 '16 at 11:51
  • I have upgraded my sed, but when running your command, I get xargs: sed: terminated by signal 13. – admirabilis Jan 01 '16 at 12:03
  • According to man 7 signal, that's SIGPIPE - broken pipe. Some command in that pipeline terminated. I guess grep - probably your grep doesn't support -z either. – muru Jan 01 '16 at 12:04
  • -z it supports, but for some reason it fails when I use -z together with -q, but that can be solved with >/dev/null. Now I'll give your command some tries, thanks! – admirabilis Jan 01 '16 at 12:09