ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I always find answers on this forum but this problem is just wrecking my head!
Please check this simple bash code:
Code:
#!/bin/bash
trap "echo 'you got me'" SIGINT SIGTERM # to trap ctrl+c
echo "Press ctrl+c during 5 sec loop"
for ((i=0;i<5;i++)); do
echo $i
sleep 1
done
read -t 1 -s tmp_with_timeout
echo "after timeout read, now press again ctrl+c during 5 sec loop"
for ((i=0;i<5;i++)); do
echo $i
sleep 1
done
echo "end"
Output looks like this:
Code:
Press ctrl+c during 5 sec loop
0
1
you got me
2
3
4
after timeout read, now press again ctrl+c during 5 sec loop
0
1
2
you got me
end
And my question: How come code behaves normally and stops when ctrl+c signal is caught and resumes, but after I use at least one timeout read in the code it looks like, if signal is caught again it doesn't pause the execution but skips the loop.
If you remove -t (timeout) option from the read, both loops look the same!
Example is very simple to demonstrate the problem. It took me few hours to finally get it from over 2500 lines of code and guys you're my last hope!
If I just want to control exit all is good, but what I want to do is after ctrl +c ask user do you want to exit [yes/no]:
If user say no and I want to continue with script, I can't because as you can see from second loop, script doesn't pause on ctrl+c signal after timeout read. Everything works perfect till I use timeout read. For some reason after that read command script don't pause anymore on signals.
I am not that good with strace so I was hoping that one of the programming gurus can explain that to me.
The lm-sensors' fancontrol script's main loop may hold the solution to this issue:
Code:
# main loop calling the main function at specified intervals
while true
do
UpdateFanSpeeds
# Sleep while still handling signals
sleep $INTERVAL &
wait $!
done
function mytrap
{
echo 'you got me'
read -p 'would you like to exit ? y/n ' ANS
if [ "$ANS" = "y" ]
then
exit
fi
}
.. seemed to test ok
Issue with timeout still occurs though... strange one
I was just reading the man page... the error may be occurring because 'read -t 1 ... ' actually returns with an error code > 128 if the timout is exceeded, I replaced the 'read -t 1' call with a 'sleep 1' and the handler works as expected
Code:
#!/bin/bash
function mytrap
{
echo 'you got me'
read -p 'would you like to exit ? y/n ' ANS
if [ "$ANS" = "y" ]
then
exit
else
return 0
fi
}
trap mytrap SIGINT SIGTERM # to trap ctrl+c
echo "Press ctrl+c during 5 sec loop"
for ((i=0;i<5;i++)); do
echo $i
sleep 1
done
#read -t 1 -s tmp_with_timeout
sleep 1
echo "after timeout read, now press again ctrl+c during 5 sec loop"
for ((i=0;i<5;i++)); do
echo $i
sleep 1
done
echo "end"
kbp:
Exactly what I have in my code! Now, with your function, try to ctrl+c in first loop answer n and then in the second loop and answer n! See the difference?! In first loop it pause and then resume after you answer n, in second loop, after timeout read it just exit the loop even if you don't answer 'y' to exit! ITS THE SAME CODE and yet it behaves differently if I use read with -t! I have no idea why!
For those who wants to try:
Code:
#!/bin/bash
trap mytrap SIGINT SIGTERM # to trap ctrl+c
function mytrap
{
echo 'you got me'
read -p 'would you like to exit ? y/n ' ANS
if [ "$ANS" = "y" ]
then
exit
fi
}
echo "Press ctrl+c during 5 sec loop"
for ((i=0;i<5;i++)); do
echo $i
sleep 1
done
read -t 1 -s tmp_with_timeout
echo "after timeout read, now press again ctrl+c during 5 sec loop"
for ((i=0;i<5;i++)); do
echo $i
sleep 1
done
kbp: Oh yes I know it works, because you comment out timeout read...now in your code please uncomment
#read -t 1 -s tmp_with_timeout
to have timeout read and check again, you will see what i mean
ps. I need timeout reads in code to avoid pauses if user is not watching.
I know it fails... that's what I was saying, if 'read -t 1 ...' doesn't receive any input before the timeout period, its return code is non-zero ( greater than 128 ) .... maybe this is the reason that the traps are handled differently
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.