我在bash脚本中启动了一些屏幕,然后runserver在每个屏幕中运行django的命令.我希望能够以编程方式阻止它们,这需要我发送Control+c给runserver.
如何从我的bash脚本发送这些击键?
Mat*_*oli 74
Ctrl+C发送SIGINT信号.
kill -INT <pid>发送SIGINT信号:
# Terminates the program (like Ctrl+C)
kill -INT 888
# Force kill
kill -9 888
Run Code Online (Sandbox Code Playgroud)
假设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
Run Code Online (Sandbox Code Playgroud)
pax*_*blo 12
CTRL-C 通常会向进程发送SIGINT信号,因此您可以执行以下操作:
kill -INT <processID>
Run Code Online (Sandbox Code Playgroud)
从命令行(或脚本),来影响具体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 ===
Run Code Online (Sandbox Code Playgroud)
它基本上启动了一个小时日志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
===
Run Code Online (Sandbox Code Playgroud)
kill -INT <pid>不完全一样要模拟ctrl+c我们首先需要了解差异。
kill -INT <pid>将INT信号发送到给定的进程(通过它找到pid)。
ctrl+c映射为intr特殊字符,当终端接收到该特殊字符时,该字符应发送INT到该终端的前台进程组。您可以通过针对给定<pid>. 这可以通过-在 kill 命令中的信号前加上 a 来完成。因此你想要的命令是:
kill -INT -<pid>
Run Code Online (Sandbox Code Playgroud)
您可以使用脚本轻松测试它:
#!/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
Run Code Online (Sandbox Code Playgroud)
资料来源: