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

发布于 2024-11-04 00:12:35 字数 170 浏览 3 评论 0原文

我在 bash 脚本中启动多个屏幕,然后在每个屏幕中运行 django 的 runserver 命令。我也希望能够以编程方式停止它们,这需要我将 Control+c 发送到 runserver

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

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 all as well, which requires me to send Control+c to runserver.

How can I send these keystrokes from my bash script?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

等你爱我 2024-11-11 00:12:35

Ctrl+C 发送 SIGINT 信号。

kill -INT 也会发送 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

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
清秋悲枫 2024-11-11 00:12:35

ctrl+ckill -INT 并不完全相同

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

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

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

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

来源:

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 <pid> 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:

风流物 2024-11-11 00:12:35

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

它基本上启动一个小时日志睡眠进程并获取其进程 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
===

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
===
女中豪杰 2024-11-11 00:12:35

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

ps -e | pgrep mysql

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

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

kill -9 13954

这将杀死 MySQL 的进程。

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 process. e.g,
13954

Now, type following command on terminal.

kill -9 13954

This will kill the process of MySQL.

蓝海 2024-11-11 00:12:35

在 Buildroot (busybox) 中我使用

killall -INT /usr/local/bin/myappname

In Buildroot (busybox) I use

killall -INT /usr/local/bin/myappname
喵星人汪星人 2024-11-11 00:12:35
    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。对我来说工作绝对很好。

    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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文