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

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.

Related

Find all running processes with a certain name linux

I am new to linux, and I want to write to a .txt file all of the running processes on my PC that has the word "con" in them.
The script I wrote:
#!/bin/bash
ps -A | grep "con" > con_proc.txt
Why is this not working?
#!/bin/bash
ps -eaf | grep -i "con" > con_proc.txt
If you want to place inside of a script the contents of the script would be the above contents, for example script.sh.
To invoke the script you will need to do the following:
chmod +x script.sh
./script.sh
The first command gives the script execute permissions and the second command invokes the script.
Linux has pgrep to do this.
$ pgrep -a con
...

Pidof not finding the process

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

Access to a process in procfs by name from bash

I want access to the status.log file of some processes, from bash terminal, in a while loop and compare them. So since the PID are not static how can I gain access to their proc/PID files with their command names and not with PID?
Try to grep output from ps -A by name of the command and get PID from there
Assuming you have pgrep (which you should, it's part of procps), call pgrep -x somecmdname to get a list of PIDs matching that string. From there you can access the proc files as usual.
e.g.
for pid in `pgrep -x somecmd`; do
echo $pid #or do something more interesting
done
Try the command pidof:
$ pidof bash
14317 10465 7204 3514 3466
Then you can loop over the pids:
$ for pid in $(pidof bash); do echo "$pid" ; done
14317
10465
7204
3514
3466
You can use this way
Example:
sleep 1000 &
cd /proc/`pidof sleep`
Refer this link man pidof

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)

How can a bash script ensure that not more than one copy of it is running?

How can a bash script ensure that not more than one copy of it is running?
I have tried:
ps -ef| grep /user/loca/shell/sh | wc -l
This shows me 2 because of the grep command. Change it to:
ps -ef | grep /user/loca/shell/sh | grep -v 'grep' wc -l
then its shows 1. However, if I then vim /user/loca/shell/sh and then execute:
ps -ef| grep /user/loca/shell/sh | grep -v 'grep' wc -l
that shows 2. But there is only one process, I have started.
How can the bash script check whether the process is running?
The idiom often used in Unix Daemons is to create a file with the PID in it when they start.
Then you can check the existence and/or content of the file when you start, if it's there, you exit and leave that instance running.
At the end of the script you delete the file, ready to run next time.
The only problem comes when the script runs, but does not complete for some reason, leaving the PID file in existence. This can be taken care of by checking its timestamp, if it's too long ago, you assume that it was an aborted run and continue with the current one.
Try pgrep instead of 'ps -ef ...' in your script:
pgrep /usr/loca/shell/sh
If that won't work then I'd resort to locking by attempting to create a symbolic link from the script if one does not exist yet and bail out if it already exists, and deleting it upon exit. Creating symbolic link is an atomic operation on unix that can be used as sort of a poorman's lock for shell scripts.
I use a file lock:
MY_LOCK_FILE='whatever.lock'
( if (flock -nx 200); then
# Do stuff here...
fi
) 200>"$MY_LOCK_FILE"

Resources