I am very new to bash scripting and I have a problem with a script.
#!/bin/sh
timestamp() {
date +"%Y-%m-%d %T"
}
LOGDIR="/home/pi/tempcontroller_rum1.log"
VALUE=28
TEMP=$(cat /home/pi/temperaturloggar/rum1.txt)
STATUS=`cat /sys/class/gpio/gpio18/value`
echo `timestamp` " Info: Temperature: $TEMP" >>$LOGDIR
if [ $TEMP -le $VALUE ] && [ $STATUS -eq 0 ]
then
echo `timestamp` "Too Cold, Heater started." >>$LOGDIR
echo "1">/sys/class/gpio/gpio18/value
print $TEMP
elif [ $TEMP -ge $VALUE ] && [ $STATUS -eq 1 ]
then
echo `timestamp` "Warm enough, Heater stoped." >>$LOGDIR
echo "0">/sys/class/gpio/gpio18/value
print $TEMP
fi
The file "rum1" contains a number that hs several decimals I think this is the problem, becouse when I runt the script I get
./tempcontroller_rum1.sh: 12: [: Illegal number: 25.10000038147
./tempcontroller_rum1.sh: 17: [: Illegal number: 25.10000038147
Any advice? I need the script to read from the .txt, compare it to the VALUE and then turn on/of the GPIO depending on if its lower or higher then the VALUE
If I manualy set the rum1.txt to 24. The script works, but I get the folowing warnings/errors.
Warning: unknown mime-type for "24" -- using "application/octet-stream"
Error: no such file "24"
How can I solve this?
My Lua script writing to the rum.txt can I round this up/dwn
commandArray = {}
if (devicechanged['Rum1']) then
local file = io.open("/home/pi/temperaturloggar/rum1.txt", "w")
file:write(tonumber(otherdevices_temperature['Rum1']))
file:close()
end
return commandArray
You can use bc to do the floating point comparison:
$ VALUE=28
$ TEMP=25.10000038147
$ bc<<<"$TEMP < $VALUE"
1
In you case :
if [ $(bc<<<"$TEMP < $VALUE") -eq 1 ] && [ $STATUS -eq 0 ]
To answer the question in the comment, use math.floor to round down, as in:
file:write(math.floor(otherdevices_temperature['Rum1']))
To round up, use
file:write(math.floor(otherdevices_temperature['Rum1']+0.5))
Now my script is working as it shuld and I wanted to post the code if anyone els is having the same question as me.
#!/bin/bash
timestamp() {
date +"%Y-%m-%d %T"
}
LOGDIR="/home/pi/tempcontroller_rum1.log"
VALUE=23
TEMP=$(cat /home/pi/temperaturloggar/rum1.txt)
STATUS=`cat /sys/class/gpio/gpio18/value`
echo `timestamp` " Info: Temperature: $TEMP" >>$LOGDIR
if [ $(bc<<<"$TEMP < $VALUE") -eq 1 ] && [ $STATUS -eq 0 ]
then
echo `timestamp` "Too Cold, Heater started." >>$LOGDIR
echo "1">/sys/class/gpio/gpio18/value
elif [ $(bc<<<"$TEMP < $VALUE") -eq 0 ] && [ $STATUS -eq 1 ]
then
echo `timestamp` "Warm enough, Heater stoped." >>$LOGDIR
echo "0">/sys/class/gpio/gpio18/value
fi
Related
function read_num(){
echo "Enter a lower limit"
read lower_limit
echo "Enter a upper limit"
read upper_limit
while [ [ $lower_limit -lt 1 ] || [ $lower_limit -gt $upper_limit ] ]
do
echo "Please enter again."
read_num
done
}
read_num
when I enter the two numbers lower and upper limit it gives the following output.
check.sh: line 6: [: too many arguments
And line number 6 is while loop
while [ [ $lower_limit -lt 1 ] || [ $lower_limit -gt $upper_limit ] ]
Here you go, this works for me:
#!/bin/bash
function read_num(){
echo "Enter a lower limit"
read lower_limit
echo "Enter a upper limit"
read uper_limit
while [[ $lower_limit -lt 1 ]] || [[ $lower_limit -gt $upper_limit ]]
do
echo "Please enter again."
read_num
done
}
read_num
Reference: Bash scripting, multiple conditions in while loop
I am trying to test if a number is in the interval [1;100] here is what I did:
var=10
if [ $["$var" -gt "1" ] -a $["$var" -lt "100"] ] ; then
echo "yes"
else
echo "no"
fi
however when I run the script I get the error message:
./yourscript:line 2 10 -gt 1:error syntax in expression ,any ideas why?
delete unnecessaries and use &&:
var=10
if [ $var -gt 1 ] && [ $var -lt 100 ] ; then #or with -a if [ $var -gt 1 -a $var -lt 100 ] ;
echo "yes"
else
echo "no"
fi
Hi I'm creating an archiving system in bash with a long and messy if statement which doesn't currently work with the current errors being on the last few lines with the else if statement. Although I expect there are further errors with this statement anyway. The variable choice is from a menu which displays in the terminal. So if they select option 1 the user then has to enter data to be written to the crontab file.
if [ $choice -eq "1" ] then
echo "Enter the MINUTE"
read minute
if [ $minute -eq 0 ] then
GLOBIGNORE=*
minute="*"
echo minute
fi
echo "Enter the Hour"
read hour
if [ $hour -eq 0 ] then
GLOBIGNORE=*
hour="*"
echo hour
fi
echo "Enter the Day"
read day
if [ $day -eq 0 ] then
GLOBIGNORE=*
day="*"
echo day
fi
echo "Enter the Month"
read month
if [ $month -eq 0 ] then
GLOBIGNORE=*
month="*"
echo month
fi
echo "Enter the weekday"
read weekday
if [ $weekday -eq 0 ] then
GLOBIGNORE=*
weekday="*"
echo weekday
fi
echo $minute $hour $day $month $weekday " date > ~/testcron.log" > testcron.txt fi
elif [ $choice -eq "2" ]
then
echo "Enter the Source and Destination Locations"
fi
There are several issues with your code:
if [ $hour -eq 0 ] then
GLOBIGNORE=*
hour="*"
echo hour
fi
In general (all test []) are missing a ; after it:
if [ $hour -eq 0 ]; then
The echo hour will not print the value of var hour but the word hour. Change to echo "$hour" (yes, quoted). Also, there is no need to set the variable GLOBIGNORE to * if vars are properly quoted.
The vars here are not quoted, that is a reason for it to fail (or to need GLOBIGNORE):
echo $minute $hour $day $month $weekday
Change to:
echo "$minute $hour $day $month $weekday"
The redirection on that same line is a plain >, that will empty the file.
If you want to append to the files, do as this:
echo "$minute $hour $day $month $weekday" "$(date >> ~/testcron.log)" >>testcron.txt
In that line there is an unneeded additional fi
This script may be of help:
get(){
read -p "$1" "$2"
if [ "$((${!2}))" -eq 0 ]; then
eval "$2"="*"
echo "${!2}"
fi
}
read -p "Choice?:" choice
if [ "$choice" -eq "1" ]; then
get "Enter the MINUTE" minute
get "Enter the Hour" hour
get "Enter the Day" day
get "Enter the Month" month
get "Enter the weekday" weekday
date >> ~/testcron.log
echo "$minute $hour $day $month $weekday" >> testcron.txt
elif [ "$choice" -eq "2" ]; then
echo "Enter the Source and Destination Locations"
fi
You are missing a semi-colon:
if [ $choice -eq "1" ]; then
or
if [ $choice -eq "1" ]
then
A semi-colon or a newline is required because the command is actually [ and has to be terminated after the ], which is just the last argument given to [.
That is the old test (or [) syntax, you could also use:
if (( choice == 1 ))
then
COUNTER=0
let COUNTER=COUNTER+1
count=`ssh -i /var/www/.ssh/id_rsa_root -o stricthostkeychecking=no $host $cmd`
count1=`echo $count | awk '{print $4}'`
printf "count1 : $count1\n"
result1=${count1/.*}
if [ "$result1" -ge "0" ]; then
echo $host
else
echo $host
exit
fi
If the value of $result1 is INTEGER and greater than zero, it'll goto IF loop (works fine for me)
But when it is not INTEGER, it is coming to else loop (which it is suppose to do) with the following error in the Output
line 55: [: : integer expression expected
but i dont want the above error in my output. I tried to use 2>/dev/null with this but no luck.
please help!
If you want to handle an empty result gracefully, check for it explicitly:
if [ -z "$result1" ]; then
: "ignoring empty string"
elif [ "$result1" -ge 0 ]; then
printf '%s\n' "$host"
else
printf '%s\n' "$host"
exit
fi
You could also check if result1 is a valid integer before making arithmetic comparisons:
function isNumber () {
[[ $1 =~ ^-?[0-9]+$ ]]
}
if ! isNumber "$result1"; then
echo "not a number"
elif [ "$result1" -ge "0" ]; then
echo "null or positive"
else
echo "negative"
fi
Change if [ "$result1" -ge "0" ]; then to
if (( result1 >= 0 )); then
This syntax won't throw any errors if result1 isn't defined (or empty) or happen to be a string somehow.
When I run this bash script :
if [ [$EUID -ne 0] ]; then
echo "This script must be run as root" 1>&2
exit 1
else
printf " whathever "
exit 0
fi
I have this error :
./myScript: 15: [: Illegal number: [
Do you see any problem ?
You have syntax error in your if condition, use this if condition:
if [ "$EUID" -ne 0 ];
OR using [[ and ]]
if [[ "$EUID" -ne 0 ]];
You have syntax error in your if condition, use this if condition:
if [ "$EUID" -ne 0 ];
OR using [[ and ]]
if [[ "$EUID" -ne 0 ]];
If you use the KSH88+/Bash 3+ internal instruction [[, it's not necessary to use doubles quotes around the variables operands :
[ ~/test]$ [[ $var2 = "string with spaces" ]] && echo "OK" || echo "KO"
OK
Instead of the external command test or his fork [ :
[ ~/test]$ [ $var2 = "string with spaces" ] && echo "OK" || echo "KO"
bash: [: too many arguments
KO
[ ~/test]$ [ "$var2" = "string with spaces" ] && echo "OK" || echo "KO"
OK
Of course, you also have to choose the operators according to the type of operands :
[ ~/test]$ var1="01"
[ ~/test]$ [ "$var1" = "1" ] && echo "OK" || echo "KO"
KO
[ ~/test]$ [ "$var1" -eq "1" ] && echo "OK" || echo "KO"
OK
two suggestions apart from what everyone else has pointed out already.
rather than doing else [bunch of code because we are root] fi, just replace the else with fi. once you've tested for the failure condition you are concerned about and taken appropriate action, no need to continue to be within the body of the conditional.
$EUID is a bashism, if you would like to make this portable to shells such as ksh, replacing it with:
if [ $(id -u) -ne 0 ]; then echo "ur not root bro"; exit 1; fi
would be a good way to do it.
using
sudo bash shell_script.sh
instead of
sudo sh shell_script.sh
solved in my case.