LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   bash: is there "ctrl-c" to kill just one command on multi commands line? (https://www.linuxquestions.org/questions/linux-software-2/bash-is-there-ctrl-c-to-kill-just-one-command-on-multi-commands-line-4175495228/)

dedec0 02-17-2014 09:01 AM

bash: is there "ctrl-c" to kill just one command on multi commands line?
 
Hi,

Is there shortcut similar to "ctrl-c" that will kill just one command on multi command line?

For example, if we execute the command:

echo a; sleep 1; echo b; sleep 3; echo c; sleep 1; echo d; sleep 1; echo e

And make a ctrl-c before "c" is echoed, the whole line is killed. I want it to kill the "sleep 3" command only, and the others after it would execute normally. Using bash's 'read' isn't really a solution because I would have to add a read between every line of every case... not easy, not pretty, seems like should exist something else.

Any ideias?

Thank you



----------------------------------
Tags: bash sh C-c ctrl-c

jdkaye 02-17-2014 10:06 AM

Look here.
jdk

harryhaller 02-17-2014 10:00 PM

control-c sends a signal to the program.

It is important to understand how individual programs react to those signals and how your script is going to react to those signals and exit/return codes.

See "man 7 signal" and "man kill"

Try writing some test programs/scripts which capture the signal by using a "trap".

read "man -P 'less +2199' bash" and "man -P 'less +4613' bash" for an explanation.

haertig 02-18-2014 01:26 AM

Not sure if this is exactly what you want, but it serves as a fun demo anyway...

Start this running:
Code:

sleep 500; echo hello >> ttt; sleep 600; echo goodbye >> ttt
Then hit ctrl-z. After that, the file "ttt" will contain "hello". Then hit ctrl-z a second time. Now the file "ttt" will contain "hello goodbye". Now run "pkill -9 sleep" to nuke the two sleep commands you suspended with those ctrl-z's.

---

To see this in action, do all the above in one window. But before starting, have a second window open running this:
Code:

while [ 1 ]; do; sleep 1; ls -l ttt; done;
And also have a third window open running this:
Code:

while [ 1 ]; do; sleep 1; ps -ef | grep sleep; done;
Get those second two windows running and scrolling, then start doing your stuff in the first window. The 2nd and 3rd windows will show you what is happening, and when. You can see the size of the "ttt" file jump when it's written to. I gave the two sleep commands different durations so you can tell them apart when looking at the ps -ef output in the third window. Note: ctrl-z does not kill the sleep commands, it merely suspends them (one suspension for each ctrl-z you hit). Therefore the command following them can execute. You have to kill the sleep's separately with pkill or some other kill variant.

RandomTroll 02-18-2014 11:26 PM

I'm not exactly sure what you want, but when I have a script executing a string of commands and one hangs up and I want to stop that particular command but not halt the script, I kill its process from another virtual terminal.

dedec0 02-22-2014 03:35 AM

Sorry, people. Now I saw that my question was a bit unclear and misleading.

Thanks for the answer, Haertig.

I wanted a key shortcut that works exactly like the ctrl-z does in your example. And in fact, ctrl-c does! LOL I even wrote a small C program to make sure the behavior with shell's commands (like sleep) wasn't different from normal programs.

But I wasn't crazy when I wrote the question, although I was distracted to one VERY important detail: it was a shell script. My need is to send a "kill the current command" for .sh scripts, but let them continue. Typing a ctrl-c with aliases and functions kills just the current one! The second question: how to fully stop a function/alias? Let it quiet for now.

So, the question is: can I kill the current command being executed inside a script? (a short and simple way, not using ps+kill bruteforce)

Some tests I used now, that anyone can repeat:

The nap.c program:
Code:

// Compile with:  gcc -Wall nap.c -o nap
// Execution: ./nap [seconds = 10]
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    int t=10;

    if (argc>1)
        t = atoi( argv[1]);

    printf("Sleeping %d seconds...\n", t);
    sleep(t);

    printf("Woke up! [%d]\n", t);
    return 0;
}

The naps.sh script:
Code:

#!/bin/bash
./nap; ./nap 2; ./nap 3; ./nap 4

Testing lines:

Code:

# ctrl-c kills a single one, you won't see "woke up" for it
./nap; ./nap 2; ./nap 3; ./nap 4

# Within an alias it also kills a single one
alias naps="./nap; ./nap 2; ./nap 3; ./nap 4"
naps        # hit ctrl anytime to kill each single instance


# Within a function too
function nnnap() { ./nap; ./nap 2; ./nap 3; ./nap 4; }
nnnap        # hit ctrl anytime to kill each single instance

# But within a shell script, is it possible?
./naps.sh



All times are GMT -5. The time now is 11:02 AM.