Two processes created by child_process.exec - node.js

I'm writing a pretty simple music server for my Raspberry Pi that will play MP#s on-demand. I can successfully launch an instance of mpg123 using child_process.exec(), but the PID of this new process differs from the process actually decoding the music. This is important to me because I want to track the process in the event of a user wanting to stop the job (child.kill()). I'm executing as follows:
var child = child_process.exec('mpg123 "' + filename + '"');
console.log(JSON.stringify({pid: child.pid});
This outputs {"pid":9444}, and music starts playing. However, when I check ps aux | grep mpg123, I see two different processes:
pi 9444 0.0 0.1 1760 504 pts/1 S+ 18:55 0:00 /bin/sh -c mpg123 "/home/pi/test.mp3"
pi 9445 11.0 0.6 14840 3112 pts/1 S+ 18:55 0:00 mpg123 /home/pi/test.mp3
This latter process, 9445, is what's actually playing my mp3. If I hang onto child and .kill() upon request, the first job is killed but the second lingers, making the kill ineffective.
Is there a different way to create a process that avoids this, or some better way to kill it? I'd rather not have to track everything (eg, the command I used to create it) and try to track down the 'correct' one based on that (eg, ps aux | grep <filename>).

According to this page, child_process.execFile(cmd, [args]) will spawn a new subshell, which is the pid of the .exec'd process. The subshell then created my instance of mpg123, which is the process I wanted to kill. Instead, I use:
var child = child_process.execFile('mpg123', [filename]); // note filename isn't enquoted
And when I want to kill it, I can simply:
child.kill(); // works

Related

"No such process" when trying to kill a running python script

I saw and tried many solutions.
I used ps aux | grep script.py to get the pid of the process. I got the following output: bioseq 24739 0.0 0.0 112884 1200 pts/1 R+ 13:20 0:00 grep --color=auto /script.py
, and then typed: kill 112884 and got the output 112884: No such process.
I also tried a similar command with grep -i, which yielded a different pid. kill <pid> also yielded <pid> No such process.
Try a pkill to kill the process, but you might also check your cron: it's possible that you kill the process but that the crontab restarts it constantly.
First of all, check whether The listed process was probably a
zombie process? therefore you cannot kill. Its live-time is depending on its parent process.
If you add the u flag to the call of ps, it displays also the STAT column which is Z for zombie processes.
if its a zombie process this has perfect explanation
How to kill zombie process
if its not a zombie process try this, killall [process name] command.
expects a process name, e.g. killall gedit which kills all such processes.
For more refer man killall

Cron job script termination

hey guys I am writing a cron job where I am executing a script like this,
0 8 * * * /home/User/ABC/all_messages.sh
So usually when I run script manually I do ctrl + C to stop the script, how do I do this in cron job? Thanks
One way to stop this manually is following:
Find the PID of the process.
ps aux | grep /home/User/ABC/all_messages.sh
You will get an output like the following:
agamaga+ 40719 0.0 0.0 23756 940 pts/22 S+ 15:39 0:00 /home/User/ABC/all_messages.sh
Here the second column is the PID, i.e. 40719 for this example.
Kill the process using the following.
kill -9 <PID>
i.e.
kill -9 40719
This should terminate the process in question.
Another way is to terminate the process using its name (Although I don't prefer this one).
pkill /home/User/ABC/all_messages.sh

Start new process after killing older one (if exists)

I have a shell script which I need to start frequently. I can set the shortcut to start (which I use to start) but not to terminate. I need to Ctrl+C to terminate it. Resultantly sometimes end up opening many processes.
So what I want to do is to add some command in the script which checks if older process from the script exists and kill it then start the new one.
Just to make my requirement more clear, I tried following
Say the running script is /home/user/runscript.sh.
ps aux | grep runscript.sh gives me
user+ 6135 0.0 0.0 16620 1492 ? S 18:28 0:00 /home/user/runscript.sh
user+ 6208 0.0 0.0 15936 952 pts/6 R+ 18:28 0:00 grep --color=auto runscript.sh
I prepended following in script
pkill -f runscript.sh
to kill the process if it is already running. It solved the purpose of killing the older process but didn't let new one start. The reason was obvious which I understood later.
What is the correct way to do this?
The typical approach to this is to use a file system based locking strategy:
The script creates a lock file (/var/lock/subsystem/...) with its own process number as content. When being started, it first checks if such file already exists. If not, all fine. But if so, then it reads the process number from the file and uses it to check the process table. If such process still exists, then it can either exit (usual behavior), or it can terminate that process (what you ask for) by sending a SIG-TERM signal.
You could just use killall instead. The trouble is that you want to avoid killing your current process, but that's easily done with the -o flag:
-o, --older-than
Match only processes that are older (started before) the time
specified. The time is specified as a float then a unit. The
units are s,m,h,d,w,M,y for seconds, minutes, hours, days,
weeks, Months and years respectively.
Therefore this ought to work:
killall -o 5s runscript.sh
The other answer is fundamentally better as it's the resilient 'professional' approach, but this approach should work if it's just for your own script and you want to take the easy way out.

In unix I used kill command by providing a ppid then it close the terminal . why? kill -9 ppid

sleep 5000
In one terminal and in second terminal I'm running:
ps -ef | grep sleep
Then I'm killing this process in second terminal by using the ppid. Then it will close the first terminal where I run the sleep command. It will not create sleep command as an orphan.
$ ps -ef | grep sleep
trainee 4887 4864 0 17:05 pts/0 00:00:00 sleep 5000
trainee 4889 4264 0 17:05 pts/1 00:00:00 grep --color=auto sleep
kill -9 4864
Why?
Presumably the parent of the sleep is your shell. When you kill that your login is terminated and your terminal closes.
The Wikipedia article on Orphan process reads (in part),
An orphan process is a computer process whose parent process has finished or terminated, though it remains running itself.
and
A process can be orphaned unintentionally, such as when the parent process terminates or crashes. The process group mechanism in most Unix-like operation systems can be used to help protect against accidental orphaning, where in coordination with the user's shell will try to terminate all the child processes with the SIGHUP process signal, rather than letting them continue to run as orphans.

How to get a list of programs running with nohup

I am accessing a server running CentOS (linux distribution) with an SSH connection.
Since I can't always stay logged in, I use "nohup [command] &" to run my programs.
I couldn't find how to get a list of all the programs I started using nohup.
"jobs" only works out before I log out. After that, if I log back again, the jobs command shows me nothing, but I can see in my log files that my programs are still running.
Is there a way to get a list of all the programs that I started using "nohup" ?
When I started with $ nohup storm dev-zookeper ,
METHOD1 : using jobs,
prayagupd#prayagupd:/home/vmfest# jobs -l
[1]+ 11129 Running nohup ~/bin/storm/bin/storm dev-zookeeper &
NOTE: jobs shows nohup processes only on the same terminal session where nohup was started. If you close the terminal session or try on new session it won't show the nohup processes. Prefer METHOD2
METHOD2 : using ps command.
$ ps xw
PID TTY STAT TIME COMMAND
1031 tty1 Ss+ 0:00 /sbin/getty -8 38400 tty1
10582 ? S 0:01 [kworker/0:0]
10826 ? Sl 0:18 java -server -Dstorm.options= -Dstorm.home=/root/bin/storm -Djava.library.path=/usr/local/lib:/opt/local/lib:/usr/lib -Dsto
10853 ? Ss 0:00 sshd: vmfest [priv]
TTY column with ? => nohup running programs.
Description
TTY column = the terminal associated with the process
STAT column = state of a process
S = interruptible sleep (waiting for an event to complete)
l = is multi-threaded (using CLONE_THREAD, like NPTL pthreads do)
Reference
$ man ps # then search /PROCESS STATE CODES
Instead of nohup, you should use screen. It achieves the same result - your commands are running "detached". However, you can resume screen sessions and get back into their "hidden" terminal and see recent progress inside that terminal.
screen has a lot of options. Most often I use these:
To start first screen session or to take over of most recent detached one:
screen -Rd
To detach from current session: Ctrl+ACtrl+D
You can also start multiple screens - read the docs.
If you have standart output redirect to "nohup.out" just see who use this file
lsof | grep nohup.out
You cannot exactly get a list of commands started with nohup but you can see them along with your other processes by using the command ps x. Commands started with nohup will have a question mark in the TTY column.
You can also just use the top command and your user ID will indicate the jobs running and the their times.
$ top
(this will show all running jobs)
$ top -U [user ID]
(This will show jobs that are specific for the user ID)
sudo lsof | grep nohup.out | awk '{print $2}' | sort -u | while read i; do ps -o args= $i; done
returns all processes that use the nohup.out file

Resources