Pidof not finding the process - linux

I want to find out a shell script process ID using pidof or ps command or any.
All i want is only the process id of it. I have used 'pidof -x test.sh'. Which is not working. Note: I don't want to invoke the /bin/sh or /bin/bash - because the script will not work. If i invoke /bin/sh in script, pidof is working.
Please help

pgrep -f script is giving the expected result.
Thanks

Another caveat even for non-script processes:
pidof ignores:
zombie processes
processes in disk sleep
So pidof as well as killall (same codebase) unlike pgrep won't not see your process as long as it is blocked in disk i/o.
I just experienced this with pidof - found, not found, found, ...

ps -ef | grep your_search_string | awk {printf $2}

both pidof and pgrep are options to find the pid for a certain process. do not run ps -ef | grep "your_command" because you have now polluted your result with the grep match too.
use pidof -s [program] to find the parent process id.
use pidof [program] to find ALL pids (ie. python is running multiple times on your system).
use pgrep [program] to match the name of your binary that is run by python (because pidof is not well suited for this use-case).
Fox explained the difference between pidof vs pgrep quite well. see his answer
I'll copy it here for convenience:
The programs pgrep and pidof are not quite the same thing, but they
are very similar. For example:
$ pidof 'firefox'
5696
$ pgrep '[i]ref'
5696
$ pidof '[i]ref'
$ printf '%s\n' "$?"
1
As you can see, pidof failed to find a match for [i]ref. This is
because pidof program returns a list of all process IDs associated
with a program called program. On the other hand, pgrep re returns a
list of all process IDs associated with a program whose name matches
the regular expression re.
In their most basic forms, the equivalence is actually:
$ pidof 'program'
$ pgrep '^program$'
As yet another concrete example, consider:
$ ps ax | grep '[w]atch'
12 ? S 0:04 [watchdog/0]
15 ? S 0:04 [watchdog/1]
33 ? S< 0:00 [watchdogd]
18451 pts/5 S+ 0:02 watch -n600 tail log-file
$ pgrep watch
12
15
33
18451
$ pidof watch
18451

Related

Pass bash command a comment to see from pkill

I have an aribtrary bash command being run that I want to attach some identifying comment to so that I may pkill it if necessary.
For example:
sleep 1000 #uniqueHash93581
pkill -f '#uniqueHash93581'
... but the #uniqueHash93581 does not get interpreted, so pkill won't find the process.
Any way to pass this unique hash so that I may pkill the process?
Bash removes comments before running commands.
A workaround with Linux and GNU grep:
Prefix your command with a variable with a unique value
ID=uniqueHash93581 sleep 1000
Later search this variable to get the PID and kill the process
grep -sa ID=uniqueHash93581 /proc/*/environ | cut -d '/' -f 3 | xargs kill
exec the command in a subshell, and use the -a option to give it a recognizable name. For example:
$ (exec -a foobar sleep 1000) &
$ ps | grep foobar
893 ttys000 0:00.00 foobar 10
Or, just run the job in the background and save its PID.
$ sleep 1000 & pid=$!
$ kill "$pid"

Get a process ID

I read a lot of questions about this argument, but I can't solve my issue.
I need to get a specific process ID and I wrote the following test.sh script:
#!/bin/sh
PID=$(ps -ef | grep abc | grep -v grep | awk '{print $2}')
echo $PID
Running this script I get two different PIDs if the abc process is not running and three different PIDs if the abc process is running.
If I run the
ps -ef | grep abc | grep -v grep | awk '{print $2}'
command from shell I get the right result.
Modifing the test.sh script removing the last awk I noticed that the script prints the following output:
user1 22153 129551 0 15:56 pts/3 00:00:00 /bin/sh ./test.sh
user1 22155 22153 0 15:56 pts/3 00:00:00 /bin/sh ./test.sh
How is it possible and how can I ignore them?
If you know exactly what is the process called, use pidof, otherwise, you can just use pgrep, it saves your grep|grep|awk....
Note that, when you ps|grep regex or pgrep regex there could be multiple entries in your result.
Do not use these tools, use the right tool meant for this, command pidof with the POSIX compatible -s flag which according to the man page says,
-s Single shot - this instructs the program to only return one
pid.
Using the above,
processID=$(pidof -s "abc")
I am not a big fan of parsing the process table. It could be inaccurate. For the same reason as "why not parse ls" You may want to look at the command pgrep
My suggestion is doing
pgrep -u user1 abc

Why can't pgrep find this process?

If I execute the following, which is just a long command that will wait forever
grep 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa abcd'
then pgrep -f can't find the process, if I search for abcd which is contained in the last segment of the long command.
ps auxww|grep abcd finds the process, but I can't use it in a script, as it also finds the grep process self.
If you remove just one a then pgrep -f abcd can find the process, but I have very long command with arguments, so I have run into this pgrep limitation.
Question
What is the correct way to check for such process based on the unique string abcd?
Your edited command is found by either of these commands:
pgrep -f abcd
or even:
ps uxww | grep '[a]bcd'
Let me try that...
$ grep 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa abcd'
Now in another terminal window:
$ pgrep grep
1842
Found it, or at least some grep process:
$ ps -f $(pgrep grep)
UID PID PPID C STIME TTY TIME CMD
501 1842 1836 0 8:59AM ttys004 0:00.00 grep aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa abcd
Yup, that was the process found.
Let's try this:
$ pgrep -f 'abcd'
1842
Seems to work for me.

How to check the path which has been a running process?

At the begining apologize for my English.
I have a running process on server, and when I execute:
ps -aux | grep script.sh
I get such a result:
root 28104 0.0 0.0 106096 1220 pts/7 S+ 08:27 0:00 /bin/bash ./script.sh
But this script is running from eg. /home/user/my/program/script.sh
So, how I can get the full path of from where the script was running? I have many scripts which name is exactly same, but they are running from different locations and I need to know from where the given script was running.
Thanks for reply!
Try the following script:
for each in `pidof script.sh`
do
readlink /proc/$each/cwd
done
This will find the pid.s of all script.sh scripts running and find the corresponding cwd (current working directories) for /proc.
use pwdx
usage: pwdx pid ...
(show process working directory)
for example,
pwdx 20102
where 20102 is the pid
this will show the process working directory of the process
#!/bin/bash
#declare the associative array with PID as key and process directory as value
declare -A dirr
#This will get the pid of the script
pid_proc=($(ps -eaf | grep "$1.sh" | grep -v "grep" | awk '{print $2}'))
for PID in ${pid_proc[#]}
do
#using Debasish method
dirr[$PID]=$(pwdx $PID)
# Below are different process to get the CWD of running process
# using user1984289 method
#dirr[$PID]=$(readlink /proc/"$PID"/cwd)
#dirr[$PID]=$(cd /proc/$PID/cwd; /bin/pwd)
done
# iterate using the keys of the associative and get the working directory
for PID in "${!dirr[#]}"
do
echo "The script '$1.sh' with PID:'$PID' is in the directory '${dirr[$PID]}'"
done
Use pgrep to get the PIDs of your instances, and then read the link of the associated CWD directory. Basically, the same approach as #user1984289 but using pgrep instead of pidof which does not match bash script names on my system (even with the -x option):
for pid in $(pgrep -f foo.sh); do readlink /proc/$pid/cwd; done
Just change foo.sh to the name of your script.

How to find a PID of a process whose name I don't know exactly?

I can get the PID of a specific process name by
pidof$(ps -C netns)
but what if I don't know the name of the process exactly?
I can't type something like
pidof$(ps -C net*)
so is there any wildcard character, or is there another solution?
Use the -A (all processes) option and filter the result through grep:
pidof $(ps -A | grep "net*")
Just use pgrep -l, eg:
$ pgrep -l sh
1821 sshd
2590 ssh-agent
2658 sh
2677 bash
3025 gvfsd-trash
14785 ksh93
17723 ksh93
try the following and see if you can discover the process as such
This will give you all processes for all users, in a full-format listing
ps auxf
where :
axu = To see every process on the system using BSD syntax
f = fullformat
if the list is too long you can filter if you have an idea of the process name
For example the command below will show you the pids for chrome.
ps auxf | grep chrome
you can use grep and pip :
pidof$(ps -c |grep yor_pattern)

Resources