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
I need a script which cuts every single username with the following command
"ps -ef | grep '[s]shd' | grep -v ^root"
After that, I want to put each user in the following group with that command
"gpasswd -a $user nginx"
Operating system: CentOs 8.2
Cutting the username out of the ps -ef output is possible but tricky and potentially fragile. You should look at the options to ps to get exactly the information you want without anything extraneous.
e.g. ps -C sshd -o user= looks to be close to what you want.
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
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;
}
I have a script that I mean to be run from cron that ensures that a daemon that I wrote is working. The contents of the script file are similar to the following:
daemon_pid=`ps -A | grep -c fsdaemon`
echo "daemon_pid: " $daemon_pid
if [ $daemon_pid -eq 0 ]; then
echo "restarting fsdaemon"
/etc/init.d/fsdaemon start
fi
When I execute this script from the command prompt, the line that echoes the value of $daemon_pid is reporting a value of 2. This value is two regardless of whether my daemon is running or not. If, however, I execute the command with back quotes and then examine the $daemon_pid variable, the value of $daemon_pid is now one. I have also tried single stepping through the script using bashdb and, when I examine the variables using that tool, they are what they should be.
My question therefore is: why is there a difference in the behaviour between when the script is executed by the shell versus when the commands in the script are executed manually? I'm sure that there is something very fundamental that I am missing.
You're very likely encountering the grep as part of the 'answer' from ps.
To help fully understand what is happening, turn off the -c option, to see what data is being returned from just ps -A | grep fsdameon.
To solve the issue, some systems have a p(rocess)grep (pgrep). That will work, OR
ps -A | grep -v grep | grep -c fsdaemon
Is a common idiom you will see, but at the expense of another process.
The cleanest solution is,
ps -A | grep -c '[f]sdaemon'
The regular expression syntax should work with all greps, on all systems.
I hope this helps.
The problem is that grep itself shows up... Try running this command with anything after grep -c:
eple:~ erik$ ps -a | grep -c asdfladsf
1
eple:~ erik$ ps -a | grep -c gooblygoolbygookeydookey
1
eple:~ erik$
What does ps -a | grep fsdaemon return? Just look at the processes actually listed... :)
Since this is Linux, why not try the pgrep? This saves you a pipe, and you don't end up with grep reporting back the daemon script itself running.
Aany process with arguments including that name will add to the count - grep, and your script.
psing for a process isn't really reliable, you should use a lock file.
As several people have pointed out already, your process count is inflated because ps | grep detects (1) the script itself and (2) the subprocess created by the backquotes, which inherits the name of the main script. So an easy solution is to change the name of the script to something that doesn't include the name you're looking for. But you can do better.
The "best-practice" solution that I would suggest is to use the facilities provided by your operating system. It's not uncommon for an init script to create a PID file as part of the process of starting your daemon; in other words, instead of just running the daemon itself, you use a wrapper script that starts the daemon and then writes the process ID to a file somewhere. If start-stop-daemon exists on your system (and I think it's fairly common these days), you can use that like so:
start-stop-daemon --start --quiet --background \
--make-pidfile --pidfile /var/run/fsdaemon.pid -- /usr/bin/fsdaemon
(obviously replace the path /usr/bin/fsdaemon as appropriate) to start it, and then
start-stop-daemon --stop --quiet --pidfile /var/run/fsdaemon.pid
to stop it. start-stop-daemon has other options that might be useful to you, which you can investigate by reading the man page.
If you don't have access to start-stop-daemon, you can write a wrapper script to do basically the same thing, something like this to start:
echo "$$" > /var/run/fsdaemon.pid
exec /usr/bin/fsdaemon
and this to stop:
kill $(< /var/run/fsdaemon/pid)
rm /var/run/fsdaemon.pid
(this is pretty crude, of course, but it should normally work).
Anyway, once you have the setup to generate a PID file, whether by using start-stop-daemon or not, you can update your check script to this:
daemon_pid=`ps --no-headers --pid $(< /var/run/fsdaemon.pid) | wc -l`
if [ $daemon_pid -eq 0 ]; then
echo "restarting fsdaemon"
/etc/init.d/fsdaemon restart
fi
(one would think there would be a concise command to check whether a given PID is running, but I don't know it).
If you don't want to (or can't) create a PID file, I would at least suggest pgrep instead of ps | grep, since pgrep will search directly for a process by name and won't find anything that just happens to include the same string.
daemon_pid=`pgrep -x -c fsdaemon`
if [ $daemon_pid -eq 0 ]; then
echo "restarting fsdaemon"
/etc/init.d/fsdaemon restart
fi
The -x means "match exactly", and -c works as with grep.
By the way, it seems a bit misleading to name your variable daemon_pid when it is actually a count.