Bash – How to check the process along with its arguments in process list

bashpsshellshell-script

I have written a script where i need to pass several arguments with the same script, the script is being executed after a certain time using cron. In order to make sure that there are no multiple instances of the scripts running, i've made a check to check if the process of the script is running using ps -ef | grep -v grep | grep Connection_Manager.sh

I want to check which arguments are being used in the running process of the script when i perform a check using ps -ef. How can i check the arguments which are being used in the running process of the script?

Best Answer

With respect to checking if the process is already running I'd change what you're doing slightly and use pgrep instead.

$ pgrep -f Connection_Manager.sh

Example

$ pgrep -f Connection_Manager.sh
16293

The -f switch allows pgrep to match the entire command line and not just the first part.

Command line arguments

For this you have a couple of methods. You could try parsing them from the output of pgrep as well. You'll need to add an additional switch, -a.

Example

$ pgrep -af Conn
17306 /bin/bash ./Connection_Manager.sh arg1 arg2

Then use awk, sed or something similar to parse their output.

sed

$ pgrep -af ./Conn | sed 's/.*Connection_Manager.sh //'
arg1 arg2

awk

$ pgrep -af ./Conn | tr '\000' ' '| awk '{print $4, $5}'
arg1 arg2

These 2 methods are off the top of my head, they could no doubt be streamlined.

Using /proc/

But depending on the number of arguments and the length this could cause you issues if the command line is overly long in length. So I'd probably go with the second method and parse the contents of the process's cmdline file. Every process has a set of files within Linux' /proc filesystem that contains meta information about that process.

$ ls /proc/19146 
attr        cmdline          environ  limits     mountinfo   numa_maps      personality  stack    task
autogroup   comm             exe      loginuid   mounts      oom_adj        root         stat     timers
auxv        coredump_filter  fd       map_files  mountstats  oom_score      sched        statm    wchan
cgroup      cpuset           fdinfo   maps       net         oom_score_adj  sessionid    status
clear_refs  cwd              io       mem        ns          pagemap        smaps        syscall

One of these files is the file cmdline. But you have to pay special attention to the contents of this file. The arguments within this file are separated by NUL characters. You can use cat -v <file> to see them in a terminal window.

$ cat -v cmdline 
/bin/bash^@./Connection_Manager.sh^@arg1^@arg2^@

This substitutes ^@ in place of the NUL's.

So parsing the contents can be done in a variety of ways, one method is discussed in @Joesph's answer, using xargs -0 .... Another is using cat -v.

Examples

xargs

$ xargs -0 < cmdline 
/bin/bash ./Connection_Manager.sh arg1 arg2

cat

$ cat -v cmdline 
/bin/bash^@./Connection_Manager.sh^@arg1^@arg2^@

You can use sed to cleanup this 2nd method a bit.

$ cat -v cmdline | sed 's/\^@/ /g'

References

Related Question