admin管理员组文章数量:1422029
Edit: thank you guys for helping me, the code I used to solve the problem is at the end of the post (*), and for the executed command output "if we consider byeprogram produce some output to stdout" I think to redirect it to a pipe, but it did not work well
I am working on project, and I faced an a issue, the issue is that I cannot catch the exit code "status code" of process that worked in background, take this program as an example, that exits with 99 if it received a sigint, the code:
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
void bye(){
// exit with code 99 if sigint was received
exit(99);
}
int main(int argc,char** argv){
signal(SIGINT, bye);
while(1){
sleep(1);
}
return 0;
}
then I compiled it using
gcc example.c -o byeprogram
in the same directory, I have my bash script:
set -x
__do_before_wait(){
##some commands
return 0
}
__do_after_trap(){
##some commands
return 0
}
runbg() {
local __start_time __finish_time __run_time
__start_time=$(date +%s.%N)
# Run the command in the background
($@) &
__pid=$!
trap '
kill -2 $__pid
echo $?
__finish_time=$(date +%s.%N)
__run_time=$(echo "$__finish_time - $__start_time" | bc -l)
echo "$__run_time"
__do_after_trap || exit 2
' SIGINT
__do_before_wait || exit 1
wait $__pid
## now if you press ctrl+c, it will execute the commands i wrote in trap
}
out=`runbg /path/to/byeprogram`
my problem is I want to catch or print the code 99, but I cannot, I tried to execute the byeprogram
from the terminal, and type ctrl+c, and it return 99, how to catch the 99 status code??
*solution:
runbg() {
# print status_code,run_time
# to get the status code use ( | gawk -F, {print $1})
# to get the run time use ( | gawk -F, {print $2})
__trap_code(){
kill -2 $__pid
wait $__pid
__status_code=$?
__finish_time=$(date +%s.%N)
__run_time=$(echo "$__finish_time - $__start_time" | bc -l)
echo "$__status_code,$__run_time"
__do_after_trap
exit 0
}
local __start_time __finish_time __run_time
__start_time=$(date +%s.%N)
($@) &
local __pid=$!
trap __trap_code SIGINT
__do_before_wait
wait $pid
__status_code=$?
__finish_time=$(date +%s.%N)
__run_time=$(echo "$__finish_time - $__start_time" | bc -l)
echo "$__status_code,$__run_time"
}
Edit: thank you guys for helping me, the code I used to solve the problem is at the end of the post (*), and for the executed command output "if we consider byeprogram produce some output to stdout" I think to redirect it to a pipe, but it did not work well
I am working on project, and I faced an a issue, the issue is that I cannot catch the exit code "status code" of process that worked in background, take this program as an example, that exits with 99 if it received a sigint, the code:
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
void bye(){
// exit with code 99 if sigint was received
exit(99);
}
int main(int argc,char** argv){
signal(SIGINT, bye);
while(1){
sleep(1);
}
return 0;
}
then I compiled it using
gcc example.c -o byeprogram
in the same directory, I have my bash script:
set -x
__do_before_wait(){
##some commands
return 0
}
__do_after_trap(){
##some commands
return 0
}
runbg() {
local __start_time __finish_time __run_time
__start_time=$(date +%s.%N)
# Run the command in the background
($@) &
__pid=$!
trap '
kill -2 $__pid
echo $?
__finish_time=$(date +%s.%N)
__run_time=$(echo "$__finish_time - $__start_time" | bc -l)
echo "$__run_time"
__do_after_trap || exit 2
' SIGINT
__do_before_wait || exit 1
wait $__pid
## now if you press ctrl+c, it will execute the commands i wrote in trap
}
out=`runbg /path/to/byeprogram`
my problem is I want to catch or print the code 99, but I cannot, I tried to execute the byeprogram
from the terminal, and type ctrl+c, and it return 99, how to catch the 99 status code??
*solution:
runbg() {
# print status_code,run_time
# to get the status code use ( | gawk -F, {print $1})
# to get the run time use ( | gawk -F, {print $2})
__trap_code(){
kill -2 $__pid
wait $__pid
__status_code=$?
__finish_time=$(date +%s.%N)
__run_time=$(echo "$__finish_time - $__start_time" | bc -l)
echo "$__status_code,$__run_time"
__do_after_trap
exit 0
}
local __start_time __finish_time __run_time
__start_time=$(date +%s.%N)
($@) &
local __pid=$!
trap __trap_code SIGINT
__do_before_wait
wait $pid
__status_code=$?
__finish_time=$(date +%s.%N)
__run_time=$(echo "$__finish_time - $__start_time" | bc -l)
echo "$__status_code,$__run_time"
}
Share
Improve this question
edited Jan 18 at 19:43
Amr Alasmer
asked Jan 17 at 15:24
Amr AlasmerAmr Alasmer
511 silver badge4 bronze badges
2
|
1 Answer
Reset to default 1When you press
CTRL-C
, the commandwait $__pid
will also be interrupted and return130
.$ sleep 999 & [1] 3222 $ wait $! ^C <-- Press ctrl-c $ echo $? 130
When you press
CTRL-C
, the assignment statementout=`runbg /path/to/byeprogram`
will also be interrupted and return130
.$ ( trap 'exit 99' INT; sleep 999 ) ^C $ echo $? 99 $ out=$( trap 'exit 99' INT; sleep 999 ) ^C <-- I'm not quite sure how SIGINT is interacting with the out= <-- assignment and the $() subshell. Need to go deep into Bash's <-- code to find out. At least the status code is not 99. $ echo $? 130
The following foo.sh
can get the 99
code (This might not be the solution to your real problem. Just show how it behaves.):
# File: foo.sh
__do_before_wait(){
##some commands
return 0
}
__do_after_trap(){
##some commands
return 0
}
runbg() {
local __start_time __finish_time __run_time
__start_time=$(date +%s.%N)
# Run the command in the background
($@) &
__pid=$!
trap '
# kill -2 $__pid
__finish_time=$(date +%s.%N)
__run_time=$(echo "$__finish_time - $__start_time" | bc -l)
echo
echo "RUN TIME: $__run_time"
__do_after_trap || exit 2
' SIGINT
sleep 9999
__do_before_wait || exit 1
wait $__pid
}
runbg ~/tmp/byeprogram
echo "RET CODE: $?"
I added a sleep 9999
before wait
. When you press CTRL-C
, it'll interrup this sleep
command so wait
will not be impacted and it can still get the job's status code as expected.
Note that I commented out kill -2 $__pid
. It is not necessary here because when your press CTRL-C
, the SIGINT
signal will also be passed to byeprogram
and kill it.
Example output:
$ bash --version
GNU bash, version 5.2.15(1)-release (x86_64-pc-linux-gnu)
$ bash foo.sh
^C
RUN TIME: 3.508632016
RET CODE: 99
本文标签: signalshow to catch status code of killed process by bash scriptStack Overflow
版权声明:本文标题:signals - how to catch status code of killed process by bash script - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745357651a2655148.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
echo $?
after thewait
line it should print 99. – Barmar Commented Jan 17 at 17:13wait
documentation: gnu./software/bash/manual/html_node/… – Barmar Commented Jan 17 at 17:14