Read input while another command is running &&

This script runs tshark, then displays the output. I want to read a keypress at all times throughout this script, especially during the 10 seconds that tshark is running. This code however, only takes input before tshark runs.

#!/bin/bash
main() {
while (( "1" == "1" )) ; do
keypress && list=`timeout 10s tshark -l -i eth0`
echo "$list"
done
}

keypress() {
read -t 5 -s -n 1 key &&
if [[ "$key" == "q" ]] ; then
echo "quit"
exit
fi
return 0
}

main

If that's the entire script and you just want to run "tshark" for 10 seconds, then wait 5 seconds and do it again. Then if you can accept typing "^c" instead of "q" to stop it, the whole thing can probably be reduced to this:

while[ 1 ]
do
    timeout 10s tshark -l -i eth0
    sleep 5
done

You may have to hit "^c" twice to stop the script sometimes.

If you want to keep the current logic, where you hit "q" to stop and that also stops the "tshark", then you need to do something more sophisticated.

You'll have to run "tshark" as a background process, capture the PID in the shell script, then if "q" is entered kill that PID before exiting.

The other problem you'll have is that the while loop will cycle every 5 seconds (since you're using "-t 5" on the read), but the "tshark" subprocess will run for 10 seconds. So you'll wind up with an ever increasing number of "tshark" processes running in parallel.

If you make the timeout on the "read" longer than the timeout on the "tshark" calls that won't be a problem, but it will also mean the pause between "tshark" runs will be longer than 5 seconds.

If you want to fix THAT problem, then you need to add logic to the shell script to make sure that you only have one "tshark" running at once.

So what to do depends on how big of a hole you want to dig for yourself. :slight_smile:

If the entire script is one logical task, then the simplest solution is to use kill 0 to terminate the entire process group.

Regards,
Alister

Hey guys, no it's not the entire script and I needed many other keys. This was just the quickest and easiest way to show the problem area. I solved it by running tshark in the background, and had to output data to /tmp since I couldn't export the variable from the subshell back to the main process. As for the time gap I used 10 seconds on both read -t and timeout. I figure since the (timeout tshark) gets called and backgrounded right before keypress is called, it should work out pretty good.

#/bin/bash
counter="1"
main() {
while {{ "$counter" <= "3" )) ; do
(timeout 10s tshark -l -i eth0 2>/dev/null > /tmp/scritp1 & ); keypress
list=$(</tmp/script1)
echo "$list"
counter=$((counter+1))
done
exit
}

keypress() {
echo "keypress"
read -t 10 -s -n 1 key &&
if [[ "$key" == "q" ]] ; then echo "quit"
exit
else main
fi
}
main