2

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

  • Hello, Happy New Year! What version of sed is this that supports null-separated new-lines? Mine doesn't: GNU sed 4.2.1. – Teresa e Junior Jan 1 '16 at 11:27
  • @TeresaeJunior You too! mine is 4.2.2. – muru Jan 1 '16 at 11:51
  • I have upgraded my sed, but when running your command, I get xargs: sed: terminated by signal 13. – Teresa e Junior Jan 1 '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 1 '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! – Teresa e Junior Jan 1 '16 at 12:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.