简体   繁体   中英

Using a bash script in linux to start and stop tail by polling for keypress

Here's what I'm trying to do, I have an arduino with temperature information going to a linux box over serial. I'm successfully reading the serial and recording it to a file with cat and then tail -f following the file. Works excellent. I want to to ad in some controls to be able to tail the file, stop tailing but continue recording, or close the program all together. So that's what I thought I had successfully done here but I'm getting the strangest errors from linux. I hate to killall cat manually I want a nice simple little interface. I've tried many different methods of achieving these results and I'm open to new approaches.

initially when I begin my program the following error occurs

./arduinodue.sh: 20: ./arduinodue.sh: [[: not found
./arduinodue.sh: 25: ./arduinodue.sh: [[: not found

if i press any key this starts scrolling down the screen

Press S to start and stop tail

Press X to close and stop recording

eventually after tapping s or x enough times I get this

Segmentation fault (core dumped)

My Code is as follows:

#!/bin/sh

#below opens serial connection

stty -F /dev/ttyACM0 cs8 19200 ignbrk -brkint -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts

cat /dev/ttyACM0 > $HOME/Due.log &     #starts cat recording serial data to Due.log as a background task
PID1=$!     #records PID of cat

nottailing2() {     #prints a message with instructions
echo "\n"
echo "Press S to start and stop tail\n"
echo "Press X to close and stop recording\n"
nottailing
}

nottailing() {     #starts a while loop waiting for a keypress I attempted running without while loop and instead used function calls to redirect the run sequence with simular results
if [ -t 0 ]; then stty -echo -icanon time 0 min 0; fi     #makes a keypress interrupt I believe but I've also attempted to run without that
while [ "x$keypress" = "x" ]; do
keypress=''
read keypress
if [[ "$keypress" == [X,x]* ]]; then     #press x to kill the script cleanly
if [ -t 0 ]; then stty sane; fi
kill $PID1
exit 1
fi
if [[ "$keypress" == [S,s]* ]]; then     #press s to start tail
if [ -t 0 ]; then stty sane; fi     #close interrupt?
break
fi
done
if [ -t 0 ]; then stty sane; fi
tailing
}

tailing() {     #same as function nottailing except it stops the tailing instead of starting it
if [ -t 0 ]; then stty -echo -icanon time 0 min 0; fi
while [ "x$keypress" = "x" ]; do
keypress=''
read keypress
if [[ "$keypress" == [X,x]* ]]; then
if [ -t 0 ]; then stty sane; fi
kill $PID1
exit 1
fi
if [[ "$keypress" == [S,s]* ]]; then
if [ -t 0 ]; then stty sane; fi
break
fi
done
if [ -t 0 ]; then stty sane; fi
nottailing2
}

nottailing2     #start the looping process

This:

./arduinodue.sh: 20: ./arduinodue.sh: [[: not found

Is a good sign that you're using code written for Bash (or another shell) but running it in a POSIX minimalist shell. Your script says /bin/sh at the top, so you can't use [[ really. If your system has Bash, change the shebang line at the top. If not, you'll need to find another way to do those checks without the fancier [[ syntax. Perhaps this:

if [ "$keypress" = S -o "$keypress" = s ]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM