How can i wait for a program to end and then automatically start a second program in the Linux console? - linux

How can I wait for a program to complete and then start another program automatically in another console?
EDIT: The first program can be long running and the other program should start right after the completion of the first program.

tail -f --pid=xyzu /dev/null && second_program
for example, in one console (terminal) invoke cat. In another console, use pstree -p | grep cat to find its process id. Then, in that other console, type tail -f --pid=6169 /dev/null && ls (replace the number with the correct one and use the needed command instead of ls). Then, end cat with CTL-C.
EDIT: Another example is, you want to shutdown the computer automatically when a long running program has completed:
first, find the pid of the long running program:
pstree -p | grep long_running_program
For instance, you find the pid 3373. Now, use the command:
sudo tail -f --pid=3373 /dev/null && shutdown -h now

Related

Catch a process which last less than a second

I'm trying to catch the exact moment a python app makes a system call to ldapsearch command and passes the user password in the command line itself.
The problem is that even with this code :
while :
do
ps -ef | grep 'ldapsearch' | grep -v 'grep' >> out
done
It seems the process is live for such a short time that the ps call misses it every time.
How can I accomplish this?
You can easyly print the log of the system calls with:
dmesg -w
with -w being the follow option.
Or if you know the PID of your process:
strace -p PID

Is there a safe way to kill a named python process from within Shell script?

Summary : Attempting to stop a python3 script safely from within shell.
I am able to kill my python3 script (called, 'getphotos.py) but am concerned that killing the process while a photo is being saved, may lead to a corrupted sd card.
Is this something I need to worry about? If so, is there a more suitable command that I could use and one that checks first if the actual script is running before quitting/exiting ?
#!/bin/bash
cd /home/pi
pgrep -f getphotos.py # will give you its pid
pkill -9 -f getphotos.py # kills the matching pid
date >> killit.txt
Try to see if there are any open handles to picture files:
(lsof -p $(pgrep -f getphotos.py) | grep -q jpg) || pkill -9 -f getphotos.py
This will kill the process only if lsof did not return any jpg files.

How to get all process ids without ps command on Linux

How to get all process ids (pid) (similar to: $ ps aux) but without using ps.
One example of when this would be used is when developing a dotnet 5 application to run on a docker host. The dotnet runtime image is a very cut-down Linux image, with bash, but without ps. When diagnosing an issue with the application, it's sometimes useful to see what processes are running and if separate processes have been spawned correctly. ps is unavailable on this image. Is there an alternative?
On Linux, all running process have "metadata" stored in the /proc filesystem.
All running process ids:
shopt -s extglob # assuming bash
(cd /proc && echo +([0-9]))
Further to the comment by #FelixJongleur42, the command
ls -l /proc/*/exe
yields a parseable output with additional info such as the process user, start time and command.
This one-liner will give you the pid and the cmd with args:
for prc in /proc/*/cmdline; { (printf "$prc "; cat -A "$prc") | sed 's/\^#/ /g;s|/proc/||;s|/cmdline||'; echo; }
Based on Ivan's example with some filtering:
for prc in /proc/*/cmdline; {
(printf "$prc "; cat -A "$prc") | sed 's/\^#/ /g;s|/proc/||;s|/cmdline||' | grep java ; echo -n;
}

How to get all of the processes' names of a shell script?

$cat t.sh
grep "12" test | wc -c
I want to know how many processes will be created when it runs.
I used
./t.sh;ps -aux | grep "t.sh"
but it didn't work because "./t.sh" had run over when ps was working.
How can I reach this goal?
Depends on the system you are running on. If you have strace you can trace all the fork system calls. problem is though that somesystems use fork, some vfork and some clone, you will have to experiment. On linux:
strace -c -f -evfork ./t.sh
should give you a summary. -c gives a count, -f means "follow" child processes, and -evfork means trace the vfork kernel call. The output goes to stderr, but you can redirect it to a file using the -o option (there are some neat tricks you can do if you specify a named pipe here).
Your mistake is the semicolon. It tells the shell to wait until t.sh finishes before running grep. Use ampersand instead to tell the shell to run t.sh in the background. Also instead of grep you'd be better off using pstree to see the list of processes spawned by your t.sh script like this:
$ ./t.sh & pstree $(pgrep t.sh)
you can try
./t.sh;ps -aux | grep -E "t.sh"
-E match exactly what you need and nothing else, I'm not on linux right now so I can't be sure, but there's something to do with that option

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