Danila Bogdan
Danila Bogdan

Reputation: 53

Killing a while loop that's running in the background without a PID

I'm a beginner in everything that is part of Linux so please take me slow.

I've created a "script" that's running in the background:

while true; do echo "I'm alive" >> alive.log ; done &

The output of the script is saved in a file alive.log that's present in the user's home directory. The problem is I have no ideea how to kill the loop since it's filling my disk space, if I wish to delete the file then loop will create a new file and fill it with the text "I'm alive" as I've asked it to do.

I tried using:

ps - aux | grep while

or

ps - aux | grep alive 

The output for the two lines will give me the PID I need but the problem is that the script is a loop which means the PID will change every time it runs itself (recursive) so I can't use the PID to kill the process.

I also tried using:

pkill while
killall while

The result for both lines is 0 (output can be seen when using pkill while -c "0" or killall while : "while: no process found";

Any suggestions please?

Upvotes: 4

Views: 10212

Answers (6)

Kishore Uppala
Kishore Uppala

Reputation: 339

In my case, I have redirected my while loop to a file and it is running in the foreground only but my session on the remote host disturbed due to VPN disconnect but somehow it is still running in the background and updating the output file. And it was also not showing in the "top" command (or) ps -ef|grep "while" to kill it.

The workaround I applied to find out the process ID (PID) that is continuously updating the file in the background is: using "fuser". fuser <file_name> outputs the PIDs that are accessing/using the output file(here: dev-dataquery.txt) . Once I killed those PIDs, the output file stopped updating.

while sleep 2; do  date ;curl `hostname -i`:8009/member|jq 2>/dev/null; done >/tmp/dev-dataquery.txt

The fuser command (Find USER) is a process management tool that identifies processes using a file, a directory, or a socket

fuser dev-dataquery.txt 
/tmp/dev-dataquery.txt: 3992317 4068085

kill -9 3992317
kill -9 4068085

Upvotes: 0

DMin
DMin

Reputation: 10363

This is an answer by @James Brown in the comments.

Type fg to get it in the foreground and kill it with ctrl-c the fastest way to solve this.

Upvotes: 2

theArcticOcean
theArcticOcean

Reputation: 26

I wrote the sentence in a script file which named while.sh, and ran it by shell:

[edemon@CentOS workspace]$ ./while.sh 
[edemon@CentOS workspace]$ 

There is not PID. I used top command tool to search my while.sh, it told me:

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                 
 4036 edemon    20   0  5268  756  436 R 97.3  0.0   0:07.93 bash                                                                    
 2469 root      20   0 94412  29m  10m S  7.8  2.0   1:49.19 Xorg                                                                    
 2788 edemon    20   0 74300  12m  10m S  1.9  0.9   1:38.79 nm-applet                                                               
 4040 edemon    20   0  2708 1072  796 R  1.9  0.1   0:00.01 top 

The while's father process is bash, so I killed 4036. The size of alive.log didn't grow any more.

Upvotes: -1

ssharma
ssharma

Reputation: 153

I decided to try out your "script" in the background. When I run

while true; do echo "I'm alive" >> alive.log ; done &

It returns a process ID to standard output, thereby showing that the process is running in the background. You can kill this process ID with:

kill <pid>

Upvotes: 1

James Brown
James Brown

Reputation: 37424

If you ran that script it's going to show as bash if you command ps -ef:

UID        PID  PPID  C STIME TTY          TIME CMD
james    27262  2448 98 17:35 pts/3    00:00:12 bash
james     2448  2446  0 Jul19 pts/3    00:04:49 bash

(if you are using bash) and its parent pid points to a bash process as well (PID 27262 is your tight little loop above). So, find all bash processes which have a bash process as a parent. This could work:

$ awk '/^james/ && $NF=="bash" && NR==FNR{a[$2];next} /^james/ && $NF=="bash" && $3 in a{print $2}' <(ps -ef) <(ps -ef)
27262
27359

So, those are good candidates for killing. In this case the other is the ps -ef and the other is the mark.

Upvotes: 1

Danila Bogdan
Danila Bogdan

Reputation: 53

Tried rebooting two times, first time didn't work but after the second the loop wasn't present anymore and file wouldn't be rewritten.

Also, after I got rid of it I reentered the script:

while true; do echo "I'm alive" >> alive.log ; done &

As stated by @ssharma when entering the script the output is a PID, even if the loop keeps changing the PID i was able to kill the loop with that PID.

Thanks for the help!

Upvotes: 0

Related Questions