Get the pid of the shell script and save it into a lockfile - linux

I do my backups with rsnapshot which creates a lockfile with the process pid inside. Now I would like to make a backup from the rsnapshots backup, so I´m looking for a way to create this lockfile for the second/external backup.
The shell script should like this:
check if a lockfile exists, if yes wait and try again(i´m doing this with a while true loop)
get the pid of this shell script and save it as a rsnapshot lockfile
start the second/external backup
delete the lockfile
How can I get the PID and save it as a rsnapshot lockfile ?

The PID is stored in $$
Like
echo $$ > thisscriptpidfile

For any application, you can find its Process ID using the Unix shell itself, using ps. Example below is a very reduced list from ps. PS will show you not only the PID, but also the owner, as well as the Parent Process ID (as in which process started this particular process.)
userX# ps -ef | more
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Oct19 ? 00:00:00 /sbin/init
root 2 0 0 Oct19 ? 00:00:00 [kthreadd]
root 3 2 0 Oct19 ? 00:00:02 [migration/0]
root 4 2 0 Oct19 ? 00:04:48 [ksoftirqd/0]
root 5 2 0 Oct19 ? 00:00:00 [migration/0]
root 6 2 0 Oct19 ? 00:00:00 [watchdog/0]
...
root 27 2 0 Oct19 ? 00:00:00 [pm]
root 28 2 0 Oct19 ? 00:00:00 rsnapshot
root 29 2 0 Oct19 ? 00:00:00 [xenbus]
Now let's start finding which Process is interesting to us. I am not familiar with rsnapshot, so I've put dummy data in the examples.
userX# ps -ef | grep rsnapshot
root 28 2 0 Oct19 ? 00:00:00 rsnapshot
ec2-user 7233 1497 0 11:32 pts/0 00:00:00 grep rsnapshot
Note that it does not give you the "header" information, only matching lines, thanks to grep.
Your second "column" is the PID. Noteworthy: ps shows every process, including the grep you just ran. Your commands/scripts need to be wary of this and strip out these items. I will use awk in the next example to do just that.
And now to expand further, getting the PID into a file. We need to confirm we have a PID, and if so, create the command to create the lock file:
userX# ps -ef | grep rsnapshot | awk '$0!~/grep/ && $2~/[0-9]/{print "echo "$2" > rsnapshot.lck"}'
echo 28 > rsnapshot.lck
If no PID for rsnapshot exists, then there will be no output. As writtent, awk will review each line, and if it does not contain the string "grep" AND there is any digit [0-9] in the second field, then print the command to be run - but not actually run the command.
The final step is to invoke the command, from the awk output.
userX# ps -ef | grep rsnapshot | awk '$0!~/grep/ && $2~/[0-9]/{print "echo "$2" > rsnapshot.lck"}' | sh
Adding "| sh" causes all output to be invoked as a command. If awk does not find rsnapshot, then there is no command to run.

Related

Could SIGKILL fail?

I've encountered this piece of behavior where even after issuing SIGKILL using kill -9 the process is not terminating. the command in question here is cat
# ps -ef | grep 19275
root 19275 1 0 08:50 ? 00:00:00 [cat]
root 22964 21578 0 09:05 pts/1 00:00:00 grep --color=auto 19275
# kill -9 19275
# echo $?
0
# ps -ef | grep 19275
root 19275 1 0 08:50 ? 00:00:00 [cat]
#
some background
I've executed this command for ((i=0; i<28; i++)); do cat </dev/zero >${i} & done as part of my test, for some strange reason when I tried to terminate this using
pkill -TERM cat did not work
pkill -9 cat did not work
kill -9 pid did not work
if memory is restriction here I do believe there is enough memory available here
# free -g
total used free shared buff/cache available
Mem: 23 18 2 0 2 3
Swap: 59 2 56
any hints ? apart from reboot
I tried your logic it worked for me with kill -9 and even with
killall cat, but it take some time to kill all 28 instances

pgrep command not returning PID

I am trying to find the PID of a process (motion_sensor.py), but pgrep returns nothing. Why does it not return the process id?
pgrep -u www-data motion_sensor.py
ps -ef | grep "motion_sensor" returns
root 7149 1 93 Apr25 ? 15:59:08 python motion_sensor.py
www-data 31872 23531 0 14:09 ? 00:00:00 sh -c sudo python /home/pi/Desktop/PiControl/motion_sensor.py
root 31873 31872 0 14:09 ? 00:00:00 sudo python /home/pi/Desktop/PiControl/motion_sensor.py
root 31874 31873 47 14:09 ? 00:14:30 python /home/pi/Desktop/PiControl/motion_sensor.py
pi 32645 32202 0 14:39 pts/0 00:00:00 grep --color=auto motion_sensor.py
Normally pgrep applies the search pattern to process names. The process name in this case is python and not motion_sensor.py. If you want to grep for the full path rather than just the process name you need to pass -f:
pgrep -u www-data -f motion_sensor.py
Check man pgrep
the requirement is to find out PID of a process,
So you can try :
ps aux | grep www-data motion_sensor.py

kill one instance of ffserver out of multiple using specific configuration file

I have two instances of ffserver running both using different configuration file kept at different path.
I want to kill one of them using a script.
when i write following command :
ps -ef |grep ffs
it gives output :
root 6421 6394 0 18:47 pts/11 00:00:00 /root/bin/ffserver -f /root/newff/ffserver.conf
root 6575 6562 0 18:49 pts/11 00:00:02 /root/bin/ffserver -f /root/test/downloaded/complete/ffserver.conf
root 8453 3720 0 19:09 pts/11 00:00:00 grep ffs
Now i want to kill only one .
Is there any way to kill using command name like i can give command name with kill
pkill_like_command /root/bin/ffserver -f /root/newff/ffserver.conf
Please tell me how to do that
as simple pkill will not work.
There is an -f switch that works for pkill, so that matching considers the full command line. You can test without killing using pgrep instead. So the command line would be for example (tested on Debian with procps 1:3.2.8-9):
pkill -f "ffserver.*/root/newff/ffserver.conf"
without pkill:
kill $( ps -ef | grep "ffserver.*/root/newff/ffserver.conf" | awk '{ print $2 }' )

When launching script in background I get two processes running

I came across a weird scenario that is stumping me.
I have a script that I launch in the background with an &
example:
root## some_script.sh &
After running it, I do a ps -ef | grep some_script and I see TWO processes running where the 2nd process keeps getting an different PID but it's Parent is the process that I started (like the parent process is spawning children that die off - but this was never written in the code).
example:
root## ps -ef | grep some_script.sh
root 4696 17882 0 13:30 pts/2 00:00:00 /bin/bash ./some_script.sh
root 4778 4696 0 13:30 pts/2 00:00:00 /bin/bash ./some_script.sh
root## ps -ef | grep some_script.sh
root 4696 17882 0 13:30 pts/2 00:00:00 /bin/bash ./some_script.sh
root 4989 4696 0 13:30 pts/2 00:00:00 /bin/bash ./some_script.sh
What gives here? It seems to be messing up the output and functionality of the script too and basically makes it a never ending process (when I have a defined start and stop in the script).
the script:
`
#! /bin/bash
# Set Global Variables
LOGDIR="/srv/script_logs"
OUTDIR="/srv/audits"
BUCKET_LS=$OUTDIR"/LSOUT_"$i"_"$(date +%d%b%Y)".TXT"
MYCMD1="aws s3api list-objects --bucket viddler-flvs"
MYCMD2="--starting-token"
MAX_ITEMS="--max-items 10000"
MYSTARTING_TOKEN='""'
rm tokenlog.txt flv_out.txt
while [[ $MYSTARTING_TOKEN != "null" ]]
do
# First - Get the token for the next batch
CMD_PRE="$MYCMD1 $MAX_ITEMS $MYCMD2 $MYSTARTING_TOKEN"
MYSTARTING_TOKEN=($($CMD_PRE | jq -r .NextToken))
echo $MYSTARTING_TOKEN >> tokenlog.txt
# Now - get the values of the files for the existing batch
# First - re-run the batch and get the file values we want
MYOUT2=$($CMD_PRE | (jq ".Contents[] | {Key, Size, LastModified,StorageClass }"))
echo $MYOUT2 | sed 's/[{},"]//g;s/ /\n/g;s/StorageClass://g;s/LastModified://g;s/Size://g;s/Key://g;s/^ *//g;s/ *$//g' >> flv_out.txt
#echo $STARTING_TOKEN
done
`
I guess you have
(
some shell instructions
)
inside of your .sh
This syntax executes commands in the new process (but command line would be the same).

In Linux,pdftoppm command is running two processes for single file

root#test:/var/lib/tomcat/webapps/logs# ps aux | grep ppm
root 25522 0.0 0.0 1844 500 ? SN 14:13 0:00 sh -c /bin/bash -c "pdftoppm -f 1 -l 1 /pdf/input.pdf test/processing/output"
root 25523 49.6 0.7 18192 12620 ? RN 14:13 0:59 pdftoppm -f 1 -l 1 /pdf/input.pdf /test/processing/output
root 25539 0.0 0.0 2016 636 ? R+ 14:15 0:00 grep ppm
I am not familiar with this command. Why two processes are running I can't understand.
These are not two pdftoppm processes. The following is the pdftoppm process:
root 25523 49.6 0.7 18192 12620 ? RN 14:13 0:59 pdftoppm -f 1 -l 1 /pdf/input.pdf /test/processing/output
The following is the process for the shell command:
root 25522 0.0 0.0 1844 500 ? SN 14:13 0:00 sh -c /bin/bash -c "pdftoppm -f 1 -l 1 /pdf/input.pdf test/processing/output"
The first line in your grep output is for the shell command that was executed. The second line was for the actual pdftoppm invocation. The third line was for the grep. (Both your shell command and grep contained the string pdftoppm, which were a part of the process list when queried.)
The shell script is most likely excuted via a system call (that's what it would be in c). This system call invokes a command processor (PID 25522 in your case) to interpret the command.
The command itselves is the process with PID 25523.
In C the exec command family executes a command without invoking a command line interpreter.

Resources