How to send control+c from a bash script?

前端 未结 5 1671
孤街浪徒
孤街浪徒 2020-12-02 11:05

I\'m starting a number of screens in a bash script, then running django\'s runserver command in each of them. I\'d like to be able to programmatically stop them

相关标签:
5条回答
  • 2020-12-02 11:36
        pgrep -f process_name > any_file_name
        sed -i 's/^/kill /' any_file_name
        chmod 777 any_file_name
        ./any_file_name
    

    for example 'pgrep -f firefox' will grep the PID of running 'firefox' and will save this PID to a file called 'any_file_name'. 'sed' command will add the 'kill' in the beginning of the PID number in 'any_file_name' file. Third line will make 'any_file_name' file executable. Now forth line will kill the PID available in the file 'any_file_name'. Writing the above four lines in a file and executing that file can do the control-C. Working absolutely fine for me.

    0 讨论(0)
  • 2020-12-02 11:39

    CTRL-C generally sends a SIGINT signal to the process so you can simply do:

    kill -INT <processID>
    

    from the command line (or a script), to affect the specific processID.

    I say "generally" because, as with most of UNIX, this is near infinitely configurable. If you execute stty -a, you can see which key sequence is tied to the intr signal. This will probably be CTRL-C but that key sequence may be mapped to something else entirely.


    The following script shows this in action (albeit with TERM rather than INT since sleep doesn't react to INT in my environment):

    #!/usr/bin/env bash
    
    sleep 3600 &
    pid=$!
    sleep 5
    
    echo ===
    echo PID is $pid, before kill:
    ps -ef | grep -E "PPID|$pid" | sed 's/^/   /'
    echo ===
    
    ( kill -TERM $pid ) 2>&1
    sleep 5
    
    echo ===
    echo PID is $pid, after kill:
    ps -ef | grep -E "PPID|$pid" | sed 's/^/   /'
    echo ===
    

    It basically starts an hour-log sleep process and grabs its process ID. It then outputs the relevant process details before killing the process.

    After a small wait, it then checks the process table to see if the process has gone. As you can see from the output of the script, it is indeed gone:

    ===
    PID is 28380, before kill:
       UID   PID     PPID    TTY     STIME      COMMAND
       pax   28380   24652   tty42   09:26:49   /bin/sleep
    ===
    ./qq.sh: line 12: 28380 Terminated              sleep 3600
    ===
    PID is 28380, after kill:
       UID   PID     PPID    TTY     STIME      COMMAND
    ===
    
    0 讨论(0)
  • 2020-12-02 11:40

    Ctrl+C sends a SIGINT signal.

    kill -INT <pid> sends a SIGINT signal too:

    # Terminates the program (like Ctrl+C)
    kill -INT 888
    # Force kill
    kill -9 888
    

    Assuming 888 is your process ID.


    Note that kill 888 sends a SIGTERM signal, which is slightly different, but will also ask for the program to stop. So if you know what you are doing (no handler bound to SIGINT in the program), a simple kill is enough.

    To get the PID of the last command launched in your script, use $! :

    # Launch script in background
    ./my_script.sh &
    # Get its PID
    PID=$!
    # Wait for 2 seconds
    sleep 2
    # Kill it
    kill $PID
    
    0 讨论(0)
  • 2020-12-02 11:40

    You can get the PID of a particular process like MySQL by using following commands: ps -e | pgrep mysql

    This command will give you the PID of MySQL rocess. e.g, 13954 Now, type following command on terminal. kill -9 13954 This will kill the process of MySQL.

    0 讨论(0)
  • 2020-12-02 11:46

    ctrl+c and kill -INT <pid> are not exactly the same, to emulate ctrl+c we need to first understand the difference.

    kill -INT <pid> will send the INT signal to a given process (found with its pid).

    ctrl+c is mapped to the intr special character which when received by the terminal should send INT to the foreground process group of that terminal. You can emulate that by targetting the group of your given <pid>. It can be done by prepending a - before the signal in the kill command. Hence the command you want is:

    kill -INT -<pid>
    

    You can test it pretty easily with a script:

    #!/usr/bin/env ruby
    
    fork {
        trap(:INT) {
            puts 'signal received in child!'
            exit
        }
        sleep 1_000
    }
    
    puts "run `kill -INT -#{Process.pid}` in any other terminal window."
    Process.wait
    

    Sources:

    • difference between both
    • propagation explanation
    0 讨论(0)
提交回复
热议问题