LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   How to terminate while loop. (https://www.linuxquestions.org/questions/programming-9/how-to-terminate-while-loop-937229/)

satishchahar 03-30-2012 03:31 AM

How to terminate while loop.
 
Hi

I started a while loop directly from terminal to read a file line by line and to run a command on each line. Post running the command I realized to modify the command and tried to stop the loop by using CTRL+C but it didn't stop. I closed that terminal directly but loop is still running. I also tried to KILL the process but it is getting started automatically with a new PID. Please suggest to stop this loop.

Thanks.

acid_kewpie 03-30-2012 03:37 AM

kill the parent process, probably a bash shell.

catkin 03-30-2012 03:51 AM

How did you start the while loop?

satishchahar 03-30-2012 03:54 AM

What I did is I searched the PID for the command running on each line and killed the same. Please suggest, how to kill parent process.

satishchahar 03-30-2012 03:55 AM

while read line
do
ldapsearch $line
done < filename

catkin 03-30-2012 03:57 AM

pstree -p will show the parents with their PIDs

colucix 03-30-2012 03:58 AM

Use the pstree command to find the parent process, e.g.
Code:

pstree -p username
specifying your username to reduce the output.

Edit: Beaten by catkin for a bunch of seconds! ;)



Hi Charles! :)

catkin 03-30-2012 03:59 AM

Quote:

Originally Posted by satishchahar (Post 4640451)
while read line
do
ldapsearch $line
done < filename

It's not obvious why that doesn't respond to multiple Ctrl+C signals, unless the ldapsearch command is programmed to ignore SIGINT.

EDIT: and doesn't exit

colucix 03-30-2012 04:00 AM

Quote:

Originally Posted by satishchahar (Post 4640451)
while read line
do
ldapsearch $line
done < filename

Have you tried to rename or move filename?

catkin 03-30-2012 04:01 AM

Quote:

Originally Posted by colucix (Post 4640454)
Edit: Beaten by catkin for a bunch of seconds! ;)

Hi Charles! :)

Hi colucix :)

We keep doing that, one way round or the other

satishchahar 03-30-2012 04:06 AM

Hi colucix

I killed the parent process but process is still running with a new parent ID.
Also tried to move the filename.

catkin 03-30-2012 04:08 AM

Try killing the parent's parent

satishchahar 03-30-2012 04:30 AM

Killing the parent process, didn't help.

catkin 03-30-2012 05:11 AM

Assuming you are not logged on as root, try killing the parent's parent and, if that doesn't work, the parent's parent's parent

AnanthaP 03-30-2012 07:48 AM

Quote:

.. terminal to read a file line by line and to run a command on each line. P ..
Also
Quote:

I also tried to KILL the process but it is getting started automatically with a new PID
Could we see the culprit script?

If it is not a live system, then shutdown -h now or shutdown -g0
`

OK.

ta0kira 03-31-2012 05:00 PM

Quote:

Originally Posted by catkin (Post 4640455)
It's not obvious why that doesn't respond to multiple Ctrl+C signals, unless the ldapsearch command is programmed to ignore SIGINT.

Or the process group isn't in the foreground, or it otherwise isn't associated with the same session as the shell. Or if a process has disabled the bindings that cause the signal to be sent from the terminal to the foreground process group. Or the process is in an uninterruptible sleep. A problem with the hard drive could cause that to happen in the "read" loop.
Kevin Barry

konsolebox 03-31-2012 11:20 PM

Check out these new functions that I just made. They might be helpful.

Code:

#!/bin/bash


# void killtree (uint <parent_pid>, [string <signal>])
#
# Creates a list of processes first then sends the signal to all of
# them synchronously.
#
function killtree {
        listtree "$1"
        kill -s "${2:-SIGTERM}" "${__A0[@]}"
}


# void killtree2 (uint <parent_pid>, [string <signal>])
#
# This version kills processes as it goes.
#
function killtree2 {
        killtree2_ "$1" "${2:-SIGTERM}"
}


# void killtree2_ (uint <pid>, string signal)
#
function killtree2_ {
        local -a LIST=()
        read -a LIST < <(exec pgrep -P "$1")
        kill -s "$2" "$1"
        if [[ ${#LIST[@]} -gt 0 ]]; then
                local A
                for A in "${LIST[@]}"; do
                        killtree2_ "$A" "$2"
                done
        fi
}


# void killtree3 (uint <parent_pid>, [string <signal>])
#
# This version kills child processes first before the parent.
#
function killtree3 {
        killtree3_ "$1" "${2:-SIGTERM}"
}


# void killtree3_ (uint <pid>, string signal)
#
function killtree3_ {
        local -a LIST=()
        if read -a LIST < <(exec pgrep -P "$1"); then
                local A
                for A in "${LIST[@]}"; do
                        killtree3_ "$A" "$2"
                done
        fi
        kill -s "$2" "$1"
}


# void killchildren (uint <parent_pid>, [string <signal>])
#
# Creates a list of child processes first then sends the signal to all
# of them synchronously.
#
function killchildren {
        listchildren "$1"
        kill -s "${2:-SIGTERM}" "${__A0[@]}"
}


# void killchildren2 (uint <parent_pid>, [string <signal>])
#
# This version kills processes as it goes.
#
function killchildren2 {
        local -a LIST=()
        read -a LIST < <(exec pgrep -P "$1")
        local A SIGNAL="${2:-SIGTERM}"
        for A in "${LIST[@]}"; do
                killtree2_ "$A" "$SIGNAL"
        done
}


# void killchildren3 (uint <parent_pid>, [string <signal>])
#
# This version kills child processes first before the parent.
#
function killchildren3 {
        local -a LIST=()
        read -a LIST < <(exec pgrep -P "$1")
        local A SIGNAL="${2:-SIGTERM}"
        for A in "${LIST[@]}"; do
                killtree3_ "$A" "$SIGNAL"
        done
}


# void listtree (uint <pid>)
#
# > uint array __A0 = list of PIDs
#
function listtree {
        __A0=("$1")
        listchildren_ "$1"
}


# void listchildren (uint <pid>)
#
# > uint array __A0 = list of PIDs
#
function listchildren {
        __A0=()
        listchildren_ "$1"
}


# void listchildren_ (uint <pid>)
#
function listchildren_ {
        local -a ADD=()
        if read -a ADD < <(exec pgrep -P "$1"); then
                local A I=${#__A0[@]}
                for A in "${ADD[@]}"; do
                        __A0[I++]=$A
                        listchildren_ "$A"
                done
        fi
}


catkin 03-31-2012 11:42 PM

Quote:

Originally Posted by ta0kira (Post 4641638)
Or the process group isn't in the foreground, or it otherwise isn't associated with the same session as the shell. Or if a process has disabled the bindings that cause the signal to be sent from the terminal to the foreground process group. Or the process is in an uninterruptible sleep. A problem with the hard drive could cause that to happen in the "read" loop.
Kevin Barry

Thanks Kevin -- that's comprehensive :)

Apart from the "hard drive problem" (which I don't understand but would like to know more about), the bash command shown would not do any of those so it would have to be ldapsearch command ... yes?

ta0kira 04-01-2012 06:49 PM

Quote:

Originally Posted by catkin (Post 4641791)
Apart from the "hard drive problem" (which I don't understand but would like to know more about)

An uninteruptible sleep is usually caused by hardware, since interrupting hardware requests can damage things. One of my old computers had a problem with the drive where it couldn't read/write properly in a certain part, and any process attempting to access that part couldn't be killed even by root with SIGKILL. This also might have also been a problem with the driver or the filesystem, though.
Quote:

Originally Posted by catkin (Post 4641791)
the bash command shown would not do any of those so it would have to be ldapsearch command ... yes?

My first thought was that we're missing some important context like, "oh yeah... I forgot to say I started the script with setsid," or something else that might prevent Ctrl+C from getting to the bash loop. If OP actually typed the posted loop as-is into a terminal that hasn't been reconfigured, then what you say is probably correct.
Kevin Barry

Reuti 04-02-2012 06:25 AM

Sometimes CTRL-C isn’t working, maybe because it’s trapped or whatever. But a CTRL-Z succeeds and than you can either kill %1 of bg %1 at your convenience.

ciuiu 04-03-2012 03:56 AM

Quote:

Originally Posted by satishchahar (Post 4640428)
Hi

I started a while loop directly from terminal to read a file line by line and to run a command on each line. Post running the command I realized to modify the command and tried to stop the loop by using CTRL+C but it didn't stop. I closed that terminal directly but loop is still running. I also tried to KILL the process but it is getting started automatically with a new PID. Please suggest to stop this loop.

Thanks.

Perhaps ctrl/z would work. Of course, I never start loop directely from terminal, but it works when executing programs made executable by g++, and for other blocking situations at runing programs.

ciuiu 04-03-2012 04:06 AM

I never star a loop from terminal. But, when I run C++ programs and a loop is infinite (the condition to stop the loop is never true), and for other blocking situations I use ctrl/z.

satishchahar 05-20-2012 12:04 PM

Now loop has been completed and terminated automatically. Thanks anyway.


All times are GMT -5. The time now is 11:07 PM.