chepurko
chepurko

Reputation: 3

bash Regular Expression in if Statement

I am stumped at the error I am getting from a script I'm trying to run to suspend my machine. I am trying to use a regex in an elif statement to suspend my machine after a specific time period.

#!/bin/bash
echo "When would you like to suspend the machine?"
read "sustime"
if [ "$sustime" = "now" ]
then
    sudo pm-suspend
elif [[ "$sustime" =~ [0-9]*[smhd] ]]
then
    time=`expr "$sustime" : '\([0-9]+)\)'`
    ttype=`expr "$sustime" : '.*\([smhd]\)'`
    sudo sleep $time$ttype ; sudo pm-suspend
else
    echo "Please enter either [now] or [#s|m|h|d]"
fi

The code doesn't work on the elif line, for example if I input 5s, the output of the script is:

$ sh dbussuspend.sh 
When would you like to suspend the machine?
5s
dbussuspend.sh: 10: dbussuspend.sh: [[: not found
Please enter either [now] or [#s|m|h|d]

However, it should read that I've entered the string 5s run the code block under elif. I've actually tried any regex in place of [0-9]*[smhd], all with the same error.

Upvotes: 0

Views: 893

Answers (1)

webb
webb

Reputation: 4340

this problem is not caused by your script, but by how you're invoking it:

sh dbussuspend.sh

should be:

bash dbussuspend.sh

bash know how to [[, but sh doesn't...

better still, do as Gordon Davisson suggests. do this once:

chmod +x dbussuspend.sh

and thenceforth, invoke like this:

./dbussuspend.sh

additionally, Etan Reisner and chepner question your use of expr, and laurel your bash regex. GNU coreutils sleep supports e.g. sleep 30s, sleep 2m, sleep 1h. check this on your system with man sleep. if so, then this will work:

elif [[ "$sustime" =~ ^[0-9]+[smhd]$ ]]
then
    sudo sleep $sustime ; sudo pm-suspend

(^ and $ in ^[0-9]+[smhd]$ to match the start and end of the string and prevent matching e.g. "uzeifue1sziufzr".)

Upvotes: 6

Related Questions