问题描述
我正在尝试在shell脚本中处理ctrl + c。我在while循环中运行代码,但是我从脚本中调用二进制文件并在后台运行它,因此当我要停止二进制文件时应该停止。代码在hello.c下面
vim hello.c
#include <stdio.h>
int main()
{
while(1)
{
int n1,n2;
printf("Enter the first number\n");
scanf("%d",&n1);
printf("Enter the second number\n");
scanf("%d",&n2);
printf("Entered number are n1 = %d,n2 =%d\n",n1,n2);
}
}
下面是我使用的Bash脚本。
#/i/bin/sh
echo run the hello binary
./hello < in.txt &
trap_ctrlc()
{
ps -eaf | grep hello | grep -v grep | awk '{print $2}' | xargs kill -9
echo trap_ctrlc
exit
}
trap trap_ctrlc SIGHUP SIGINT SIGTERM
启动脚本后,hello二进制文件将连续运行。我已经使用kill -9 pid命令从其他终端杀死了此二进制文件。
我已经尝试过这个trap_ctrlc函数,但是它不起作用。如何在Shell脚本中处理Ctrl + c。
在in.txt中,我添加了输入,因此我可以将此文件直接传递给二进制文件
vim in.txt
1
2
输出:
输入第一个号码
输入第二个数字
输入的数字为n1 = 1,n2 = 2
输入第一个号码
输入第二个数字
输入的数字为n1 = 1,n2 = 2
输入第一个号码
输入第二个数字
输入的数字为n1 = 1,n2 = 2
并且持续不断。
解决方法
更改您的c程序,以便它检查读取数据是否真的成功:
#include <stdio.h>
int main()
{
int n1,n2;
while(1) {
printf("Enter the first number\n");
if(scanf("%d",&n1) != 1) return 0; /* check here */
printf("Enter the second number\n");
if(scanf("%d",&n2) != 1) return 0; /* check here */
printf("Entered number are n1 = %d,n2 =%d\n",n1,n2);
}
}
当in.txt
的输入耗尽时,它将终止。
要制作可以从in.txt
读取很多次的内容,您可以在bash脚本中创建一个循环,该循环可以永远为./hello
供电(或直到被杀死)。
示例:
#!/bin/bash
# a function to repeatedly print the content in "in.txt"
function print_forever() {
while [ 1 ];
do
cat "$1"
sleep 1
done
}
echo run the hello binary
print_forever in.txt | ./hello &
pid=$!
echo "background process $pid started"
trap_ctrlc() {
kill $pid
echo -e "\nkill=$? (0 = success)\n"
wait $pid
echo "wait=$? (the exit status from the background process)"
echo -e "\n\ntrap_ctrlc\n\n"
}
trap trap_ctrlc INT
# wait for all background processes to terminate
wait
可能的输出:
$ ./hello.sh
run the hello binary
background process 262717 started
Enter the first number
Enter the second number
Entered number are n1 = 1,n2 =2
Enter the first number
Enter the second number
Entered number are n1 = 1,n2 =2
Enter the first number
^C
kill=0 (0 = success)
wait=143 (the exit status from the background process)
trap_ctrlc
另一种选择是杀死wait
后杀死孩子:
#!/bin/bash
function print_forever() {
while [ 1 ];
do
cat "$1"
sleep 1
done
}
echo run the hello binary
print_forever in.txt | ./hello &
pid=$!
echo "background process $pid started"
trap_ctrlc() {
echo -e "\n\ntrap_ctrlc\n\n"
}
trap trap_ctrlc INT
# wait for all background processes to terminate
wait
echo first wait=$?
kill $pid
echo -e "\nkill=$? (0 = success)\n"
wait $pid
echo "wait=$? (the exit status from the background process)"`
``