如何从 bash 脚本发送 control+c?

问题描述 投票:0回答:6

我在 bash 脚本中启动多个屏幕,然后在每个屏幕中运行 django 的

runserver
命令。我也希望能够以编程方式停止它们,这需要我将
Control+c
发送到
runserver

如何从 bash 脚本发送这些击键?

bash gnu-screen
6个回答
109
投票

Ctrl+C 发送

SIGINT
信号。

kill -INT <pid>
也发送
SIGINT
信号:

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

假设

888
是您的进程 ID。


请注意,

kill 888
发送一个
SIGTERM
信号,该信号略有不同,但也会要求程序停止。因此,如果您知道自己在做什么(程序中没有绑定到
SIGINT
的处理程序),一个简单的
kill
就足够了。

要获取脚本中启动的最后一个命令的 PID,请使用

$!
:

# Launch script in background
./my_script.sh &
# Get its PID
PID=$!
# Wait for 2 seconds
sleep 2
# Kill it
kill $PID

15
投票

CTRL-C 通常会向进程发送 SIGINT 信号,因此您可以简单地执行以下操作:

kill -INT <processID>

从命令行(或脚本),影响特定的

processID

我说“一般”是因为,与大多数 UNIX 一样,这几乎是无限可配置的。如果执行

stty -a
,您可以看到哪个键序列与
intr
信号相关联。这可能是 CTRL-C 但该键序列可能会完全映射到其他内容。


以下脚本显示了这一操作(尽管使用

TERM
而不是
INT
,因为
sleep
在我的环境中不会对
INT
做出反应):

#!/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 ===

它基本上启动一个小时日志

sleep
进程并获取其进程 ID。然后它会在终止进程之前输出相关的进程详细信息。

短暂等待后,它会检查进程表以查看进程是否已消失。从脚本的输出中可以看到,它确实消失了:

===
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
===

14
投票

ctrl+c
kill -INT <pid>
不完全相同

要模拟 ctrl+c,我们需要首先了解其中的区别。

kill -INT <pid>
将向给定进程发送
INT
信号(通过其
pid
找到)。

ctrl+c 映射到

intr
特殊字符,当终端接收到该字符时,应将
INT
发送到该终端的前台进程组。您可以通过定位给定
<pid>
的组来模拟这一点。可以通过在kill命令中的
-
之前添加
<pid>
来完成。因此你想要的命令是:

kill -INT -<pid>

您可以使用脚本轻松测试它:

#!/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

来源:


0
投票

您可以使用以下命令获取特定进程(例如 MySQL)的 PID:

ps -e | pgrep mysql

此命令将为您提供 MySQL 进程的 PID。例如, 13954

现在,在终端上输入以下命令。

kill -9 13954

这会杀死 MySQL 进程。


0
投票

在 Buildroot (busybox) 中我使用

killall -INT /usr/local/bin/myappname

-1
投票
    pgrep -f process_name > any_file_name
    sed -i 's/^/kill /' any_file_name
    chmod 777 any_file_name
    ./any_file_name

例如“pgrep -f firefox”将 grep 运行“firefox”的 PID,并将该 PID 保存到名为“any_file_name”的文件中。 'sed' 命令将在 'any_file_name' 文件中的 PID 号开头添加 'kill'。第三行将使“any_file_name”文件可执行。现在第四行将杀死文件“any_file_name”中可用的 PID。将以上四行写入一个文件并执行该文件即可完成control-C。对我来说工作绝对很好。

© www.soinside.com 2019 - 2024. All rights reserved.