I'm currently working on a college project where I have to do several shell script files. In one of them, I have to create a file called taunt.sh
that uses the command cowsay
to print some messages depending on some actions:
taunt.sh
script should issue a funny message and finish/exit.SIGHUP
signal, then it should issue a special message and exit.SIGINT
or SIGTERM
, then it should issue a taunt and terminate/exit.The thing is, I need to use #!/bin/sh
and not #!/bin/bash
.
I know in bash
we can use read -t 10 input
to wait for 10 seconds while an input is received, and we could exit of the waiting process after receiving some input.
But this is not an option in sh
.
So, is there a way to implement some similar functionality in sh
?
I tried this
#!/bin/sh
echo "Enter your input:"
sleep 10 &
read input
kill $! 2>/dev/null
if [ -z "$input" ]; then
echo "No input provided"
else
echo "You entered: $input"
fi
But it never got out after 10 seconds, only if I typed something.
I'm pretty new to sh
and still takes me a while to understand some things. So I hope somebody can help me with this.
Here a POSIX
version of the bash's read -t 10
:
#!/usr/bin/env sh
timeout=10
mystty="$(stty -g)"
trap 'stty "$mystty"' EXIT
stty -icanon min 0 time $((timeout*10))
echo "Enter your input "
read input
if [ -z "$input" ]; then
echo "No input provided"
else
echo "You entered: $input"
fi
mystty="$(stty -g)"
save stty
settings in a variabletrap 'stty "$mystty"' EXIT
: This line set a trap for the EXIT
¹ signal. In this case, when the script exits, it will restores those settings in any cases (ctrl+c or any exit cases) for the following terminal modifications :stty -icanon min 0 time 100
: This line modifies the terminal settings using the stty
command. The -icanon
flag disables canonical mode, which means that input is processed immediately, without waiting for a newline character. The min 0
setting means that the terminal will not wait for any characters to be typed before returning input. The time 100
set a timeout of 100 deciseconds (10 seconds) to read input. In this mode, if no input is received within the specified timeout, the read operation will return immediately.