how to store information about detached child process in nodejs command line application - node.js

I am building a nodejs commmand line application that starts several detached child processes. Some of them are express severs listening to at a specified port.
As I mentioned these processes are detached. How do i store information about these detached child processes like pid to kill them when the user wants.
I have tried writing them into a generic file which I later read to get the data.
Is there a better way?

You don't really have to keep track of all child process for terminating them. You can kill all the child process using their Process Group ID (PGID).
PGID=$(ps opgid= "$PID" | tr -d ' ')
kill -- -$PGID
You will get parent process Id (PID) by
ps aux | grep "process_name" | awk '{print $2}'
In your case the process name will be "node"

Related

Get internal docker PID by system PID

After I use exec command inside docker container I can get the PID with exec inspect. The problem is that this ID is not local to the container but a system PID. So I would get something like 22620 while the PID inside docker container is 695.
I know that docker uses process namespaces to isolate its processes. So I have tried to get the internal PID with
cat /proc/22620/status | grep NSpid
. This indeed gave me the PID I was looking for:
NSpid: 22620 695
But I need to parse this string to get the PID.
Is there a proper way to get the PID used by the docker container?
PS.
I need this process ID to kill the process started by other exec call. I cannot kill the system process as it is owned by root and I cannot use sudo.
Och. Use cut to filter a section from a line.
grep NSpid /proc/24918/status | cut -f3
Will give 695 from the example.

Manually stopping Spark Workers

Is there a way to stop a Spark worker through the terminal? I'm aware of the scripts: start-all.sh, stop-all.sh, stop-workers.sh, etc. However, everytime I run start-all.sh there seems to be residual workers from a previous Spark cluster instance that are also spawned. I know this because the Worker Id contains the date and timestamp of when the worker was created.
So when I run start-all.sh today, I see the same 7 or so workers that were created at the beginning of April.
Is there a way to kill these earlier workers? Or perhaps a way to grep for their process names?
This has happened to me in the past and what I usually do is:
1) Find the process id:
ps aux | grep spark
2) And kill it:
sudo kill pid1
You can do either:
for pid in $(ps aux | grep spark | awk '{print $2}'); do kill -9 $pid; done
or
for pid in $(jps | grep Worker | awk '{print $1}'); do kill -9 $pid; done
I would suggest that you use the second one so that you don't kill something accidentally since the first one will also show pid for grep and maybe something else that you might have running.
Explanation (might be helpful for new users):
In the pipeline, we have ps (gives us the currently running processes) or jps (jvm process status tool, which gives us the process ids for the processes in the jvm).Then we grep and according to output we grab the pid with the help of awk.
In the loop, kill command with signal -9 (SIGKILL i.e. forced termination, not recommended should be used as last resort). Bye bye process.
To kill a spark worker using spark daemons:
ssh <host-name-where-worker-is-running>
spark-3.3.0-bin-hadoop3/sbin/spark-daemon.sh stop org.apache.spark.deploy.worker.Worker 1
sudo sh -c "sync; echo 3 > /proc/sys/vm/drop_caches"
To start it back again:
spark-3.3.0-bin-hadoop3/sbin/spark-daemon.sh start org.apache.spark.deploy.worker.Worker 1
Ideally, spark-3.3.0-bin-hadoop3 should be your ${SPARK-HOME}. Also, ensure to clear your memory caches when you kill the spark worker/executor

How to identify a job given from your user account and kill it

I had given a job in a remote server yesterday from my home. The command was
sh run.sh >& out &
The run.sh will excute a program (average.f) more than 1000 times recurssively.
Today, in my office, I found some mistake in my run.sh. So I would like to kill it.
I used top command, but it is not showing the run.sh. It is only showing average.f. So, once, I killed it with kill PID, it is again starting average.f with another PID and producing outputs.
ps -u is not showing either run.sh or average.f.
Can anybody please help me how to kill this job.
find your job id with the process or application name . example is given below - I am killing java process here
ps -aef|grep java
// the above command will give you pid, now fire below command to kill that job
kill -9 pid
// here pid is a number which you get from the first command
ps -ef | grep run.sh | grep -v grep | awk '{print $2}' | xargs kill -9
Use pstree(1) (probably as pstree -p) to list the process tree hierarchy, then kill(1) (first with -TERM, then with -QUIT, and if that does not work, at last with -KILL) your topmost shell process running run.sh (or else the few "higher" processes). Perhaps use killall(1) or pidof(1) (or pgrep(1) or pkill)
You might want to kill the process group, with a negative pid.
You should never at first kill -KILL a process (but only at last resort); some programs (e.g. database servers, sophisticated numerical computations with application checkpointing, ...) have installed a SIGTERM or SIGQUIT signal handler to clean up their mess and e.g. save some state (on the disk) in a sane way. If you kill -KILL them, they could leave the mess uncleaned (since SIGKILL cannot be caught, see signal(7)....)
BTW, you should use ps auxw to list all processes, read ps(1)

How to get child process from parent process

Is it possible to get the child process id from parent process id in shell script?
I have a file to execute using shell script, which leads to a new process process1 (parent process). This process1 has forked another process process2(child process). Using script, I'm able to get the pid of process1 using the command:
cat /path/of/file/to/be/executed
but i'm unable to fetch the pid of the child process.
Just use :
pgrep -P $your_process1_pid
I am not sure if I understand you correctly, does this help?
ps --ppid <pid of the parent>
I've written a script to get all child process pids of a parent process.
Here is the code. Hope it will help.
function getcpid() {
cpids=`pgrep -P $1|xargs`
# echo "cpids=$cpids"
for cpid in $cpids;
do
echo "$cpid"
getcpid $cpid
done
}
getcpid $1
To get the child process and thread,
pstree -p PID.
It also show the hierarchical tree
The shell process is $$ since it is a special parameter
On Linux, the proc(5) filesystem gives a lot of information about processes. Perhaps
pgrep(1) (which accesses /proc) might help too.
So try cat /proc/$$/status to get the status of the shell process.
Hence, its parent process id could be retrieved with e.g.
parpid=$(awk '/PPid:/{print $2}' /proc/$$/status)
Then use $parpid in your script to refer to the parent process pid (the parent of the shell).
But I don't think you need it!
Read some Bash Guide (or with caution advanced bash scripting guide, which has mistakes) and advanced linux programming.
Notice that some server daemon processes (wich usually need to be unique) are explicitly writing their pid into /var/run, e.g. the  sshd server daemon is writing its pid into the textual file /var/run/sshd.pid). You may want to add such a feature into your own server-like programs (coded in C, C++, Ocaml, Go, Rust or some other compiled language).
You can get the pids of all child processes of a given parent process <pid> by reading the /proc/<pid>/task/<tid>/children entry.
This file contain the pids of first level child processes.
Recursively do this for all children pids.
For more information head over to https://lwn.net/Articles/475688/
ps -axf | grep parent_pid
Above command prints respective processes generated from parent_pid, hope it helps.
+++++++++++++++++++++++++++++++++++++++++++
root#root:~/chk_prgrm/lp#
parent...18685
child... 18686
root#root:~/chk_prgrm/lp# ps axf | grep frk
18685 pts/45 R 0:11 | \_ ./frk
18686 pts/45 R 0:11 | | \_ ./frk
18688 pts/45 S+ 0:00 | \_ grep frk
You can print the PID of all child processes invoked by a parent process:
pstree -p <PARENT_PID> | grep -oP '\(\K[^\)]+'
This prints a list of pids for the main process and its children recursively
I used the following to gather the parent process and child processes of a specific process PID:
ps -p $PID --ppid $PID --forest | tail -n +2 | awk '{print$1}'
Note, this will not work to find child processes of child processes.
For the case when the process tree of interest has more than 2 levels (e.g. Chromium spawns 4-level deep process tree), pgrep isn't of much use. As others have mentioned above, procfs files contain all the information about processes and one just needs to read them. I built a CLI tool called Procpath which does exactly this. It reads all /proc/N/stat files, represents the contents as a JSON tree and expose it to JSONPath queries.
To get all descendant process' comma-separated PIDs of a non-root process (for the root it's ..stat.pid) it's:
$ procpath query -d, "..children[?(#.stat.pid == 24243)]..pid"
24243,24259,24284,24289,24260,24262,24333,24337,24439,24570,24592,24606,...
#include<stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
// Create a child process
int pid = fork();
if (pid > 0)
{
int j=getpid();
printf("in parent process %d\n",j);
}
// Note that pid is 0 in child process
// and negative if fork() fails
else if (pid == 0)
{
int i=getppid();
printf("Before sleep %d\n",i);
sleep(5);
int k=getppid();
printf("in child process %d\n",k);
}
return 0;
}

pkill kills sshd process started by other user in parent shell

I have a script that runs from a newly created shell.
OS is Red Hat Enterprise Linux Server release 5.4 (Tikanga).
In certain point when the script detects that some application (started by the script) is hanging the script tries to terminate all the procesess it started. I assumed that the correct command for terminating all processes started by current user in current shell is:
pkill /?
The problem is that it kills sshd that is started in parent shell (by init.d) and the putty console disconnects showing error message.
I wonder:
How is it possible for specific user in specific shell to terminate process started by other user in parent shell?
What would be correct command to terminate all processes started by the script currently running?
I have found some solution where i store all the PIDs and when the script needs to terminate them I run in the loop the following:
[ws#RHDev ~]# pkill $(ps aux | grep $pid | awk '{print $2}')
However, I am looking for one-liner that simply terminates all the processes started by the current script.
You can filter subprocesses by the current process pid. The ps command can do this using the --ppid parameter.
ps opid --ppid=7051 | tail -n +2 | xargs kill
here tail -n +2 is to strip the ps headers.
I assumed that the correct command for terminating all processes started by current user in current shell is:
pkill /?
This command matches every single process in the system because it effectively requires only 0 symbols from process name to match. pgrep -l /? demonstrates that.
How is it possible for specific user in specific shell to terminate process started by other user in parent shell?
From man kill(2):
For a process to have permission to send a signal it must either be
privileged (under Linux: have the CAP_KILL capability), or the real or
effective user ID of the sending process must equal the real or saved
set-user-ID of the target process. In the case of SIGCONT it suffices
when the sending and receiving processes belong to the same session.
Do you invoke pkill from user root?
What would be correct command to terminate all processes started by the script currently running?
When bash starts it creates its own process group. Child processes it creates are put in the same process group. Hence:
kill -- -$$
Kills all processes started by the current script. Provided that those processes didn't become group leaders.

Resources