This question already has answers here:
Command not found error in Bash variable assignment
(5 answers)
Closed 3 years ago.
echo "Enter the current time: "
read h m s
s = `expr $n + 1`
if [ $n -eq 60 ]; then
s = 0
m = `expr $m + 1`
if [ $m -eq 60 ]; then
m = 0
h = `expr $h + 1`
if [ $h -eq 24 ]; then
h = 0
fi
fi
fi
echo "The time after one second is $h $m $n"
If you type s = 0 in a bash prompt, you will get bash: s: command not found.
The correct way to assign a variable in bash is s=0 without the spaces.
Related
This question already has answers here:
Why should there be spaces around '[' and ']' in Bash?
(5 answers)
using OR in shell script
(2 answers)
Closed 7 months ago.
here is my simple script prova.sh:
#!/bin/bash
echo "\$# = [$#]"
echo "\$1 = [$1]"
if [ $# -ge 2 || $1="-h" ]
then
echo "#########################################################################"
echo -e "usage: $0 \t launches the program only"
echo -e " $0 -s\t shows the command fired and launches the program"
echo -e " $0 -so\t shows only the command fired"
echo -e " $0 -h\t shows this guide"
echo "#########################################################################"
exit 0
fi
command="ls -la"
if test "$1"="-so" || "$1"="-s"
then
echo "Fired command:"
echo $command
fi
if test "$1"!="-so"
then
$command
fi
here is the output:
$> ./prova.sh -h
$# = [1]
$1 = [-h]
./prova.sh: row 6 : [: "]" missing
./prova.sh: row6: -h=-h: command not found
Fired command:
ls -l
totale 4
-rwxrw-r--. 1 user user 632 20 lug 16.13 prova.sh
I expected just the help
you need to close every test using single brackets, the shell way, if [ $# -ge 2 ] || [ $1 = "-h" ]; then ... this will fix it. If you still use single brackets way, is safe to enclose you variables with double quotes, so if they are empty, you are safe, like this if [ "$#" -ge 2 ] || [ "$1" = "-h" ]; then ... or you can just put them inside a double bracket, and bash will handle this for you if [[ $# -ge 2 || $1 = "-h" ]]; then ...
I'm trying to write a bash script for
"Given a positive integer N greater than 1, make a script to show the
even numbers between 0 and N. Ex .: The number 12 has been read. The
program must have as output: 0, 2, 4, 6, 8, 10 and 12;"
So far I did like this:
ex5.sh
#!/bin/bash
echo "Number :"
read num;
for (( i = 1; i >= $num; i++ ))
do
if [ $(($i % 2)) -eq 0 ]
then
echo $i
fi
done
When i compile, it doesn't print numbers. I couldn't find where is the problem
I tried using for-in loop as well
#!/bin/bash
echo "Number :"
read num;
for i in $num
do
if [ $(($i % 2)) -eq 0 ]
then
echo $i
fi
done
This time only print the number that i put as a input. For example, I put 4 in terminal it prints 4 as well
Many thanks
This way can make your code working:
echo -n "Number : "
read num;
for i in $(seq 0 $num)
do
if [ $(expr $i % 2) == 0 ]
then
echo $i
fi
done
bash ex5.sh
Number : 12
0
2
4
6
8
10
12
`
echo -n "Number : "
read num;
for i in $(seq 0 $num)
do
if [ $((num%2)) -eq 0 ]
then
echo $i
fi
done
`
#!/bin/bash
read -p "Number: " num
awk '{for(i=0;i<=$1;i++) if(i%2 == 0) print i}'<<<$num
./printNumbers.sh
Number: 8
0
2
4
6
8
# to get a list use printf
awk '{for(i=0;i<=$1;i++) if(i%2 == 0) printf i","}'<<<$num | sed 's/,$//'
./printNumbers.sh
Number: 8
0,2,4,6,8
#!/usr/bin/env bash
read -p 'Number: ' num
seq 0 2 "$num"
it's <= not >=
#!/bin/bash
echo "Number :"
read num;
for (( i = 1; i <= $num; i++ ))
do
if [ $(($i % 2)) -eq 0 ]
then
echo $i
fi
done
I'm trying to implement for loops instead of while loops but have no idea how too. This is a while loop script I created. How would I make this into a for loop instead of a while loop? I'm not really understanding how for loops work.
#!/bin/bash
read -p "Number of Papers To Grade:
" numpap
av=$numpap
while [ $av -gt 0 ];
do
av=$(($av - 1))
echo "Enter a Number (1-100): "
read num
if [[ $num -ge 1 && $num -le 100 ]] ; then
echo ""
else
echo "Enter a Number Between 1-100
"
av=$(($av + 1))
total=$(($total - num))
fi
total=$(($total + num))
done
averag=$(($total/$numpap))
echo Average Grade = $averag%
echo "Done"
#!/bin/bash
var=5
for ((value=var; value>0; --value))
do
echo $value
done
This gives the output :
5
4
3
2
1
You can have a look at more ways to write loops using while / for / until : here
I modified your script to run using a for loop:
#!/bin/bash
read -p "Number of Papers To Grade:" numpap
for ((av=numpap; av>0; av--))
do
echo "Enter a Number (1-100): "
read num
if [[ $num -ge 1 && $num -le 100 ]] ; then
echo ""
else
echo "Enter a Number Between 1-100"
av=$(($av + 1))
total=$(($total - num))
fi
total=$(($total + num))
done
averag=$(($total/$numpap))
echo Average Grade = $averag%
echo "Done"
I have a simple script in Bash to read a number in a file and then compare it with a different threshold. The output is this:
: integer expression expected
: integer expression expected
OK: 3
My code is this:
#!/bin/bash
wget=$(wget http://10.228.28.8/ -O /tmp/wget.txt 2>/dev/null)
output=$(cat /tmp/wget.txt | awk 'NR==6')
#output=7
echo $output
if [ $output -ge 11 ];then
echo "CRITICAL: $output"
exit 2
elif [ $output -ge 6 ] && [ $output -lt 11 ];then
echo "WARNING: $output"
exit 1
else
echo "OK: $output"
exit 0
fi
rm /tmp/wget.txt
I know what is the problem, I know that I'm reading a string and I try to compare a int. But I don't know how can I do to read this file and convert the number to read in a int var..
Any ideas?
The problem occurs when $output is the empty string; whether or not you quote the expansion (and you should), you'll get the integer expression required error. You need to handle the empty string explictly, with a default value of zero (or whatever default makes sense).
wget=$(wget http://10.228.28.8/ -O /tmp/wget.txt 2>/dev/null)
output=$(awk 'NR==6' < /tmp/get.txt)
output=${output:-0}
if [ "$output" -ge 11 ];then
echo "CRITICAL: $output"
exit 2
elif [ "$output" -ge 6 ];then
echo "WARNING: $output"
exit 1
else
echo "OK: $output"
exit 0
fi
(If you reach the elif, you already know the value of $output is less than 11; there's no need to check again.)
The problem also occurs, and is consistent with the error message, if output ends with a carriage return. You can remove that with
output=${output%$'\r'}
There are a couple of suggestions from my side regarding your code.
You could explicitly tell bash the output is an integer
declare -i output # See [1]
Change
output=$(cat /tmp/wget.txt | awk 'NR==6') # See [2]
may be better written as
output=$(awk 'NR==6' /tmp/wget.txt )
Change
if [ $output -ge 11 ]
to
if [ "0$output" -ge 11 ] # See [4]
or
if (( output >= 11 )) # Better See [3]
References
Check bash [ declare ].
Useless use of cat. Check [ this ]
Quoting [ this ] answer :
((...)) enable you to omit the dollar signs on integer and array variables and include spaces around operators for readability. Also empty variable automatically defaults to 0 in such a statement.
The zero in the beginning of "0$output" help you deal with empty $output
Interesting
Useless use of cat is a phrase that has been resounding in SO for long. Check [ this ]
[ #chepner ] has dealt with the empty output fiasco using [ bash parameter expansion ] in his [ answer ], worth having a look at.
A simplified script:
#!/bin/bash
wget=$(wget http://10.228.28.8/ -O /tmp/wget.txt 2>/dev/null)
output=$(awk 'NR==6' </tmp/wget.txt )
output="$(( 10#${output//[^0-9]} + 0 ))"
(( output >= 11 )) && { echo "CRITICAL: $output"; exit 2; }
(( output >= 6 )) && { echo "WARNING: $output"; exit 1; }
echo "OK: $output"
The key line to cleanup any input is:
output="$(( 10#${output//[^0-9]} + 0 ))"
${output//[^0-9]} Will leave only digits from 0 to 9 (will remove all non-numeric chars).
10#${output//[^0-9]} Will convert output to a base 10 number.
That will correctly convert numbers like 0019
"$(( 10#${output//[^0-9]} + 0 ))" Will produce a zero for a missing value.
Then the resulting number stored in output will be compared to limits and the corresponding output will be printed.
In BASH, It is a good idea to use double brackets for strings:
if [[ testing strings ]]; then
<whatever>
else
<whatever>
fi
Or double parenthesis for integers:
if (( testing ints )); then
<whatever>
else
<whatever>
fi
For example try this:
var1="foo bar"
if [ $var1 == 'foo bar' ]; then
echo "ok"
fi
Result:
$ bash: [: too many arguments
Now, this:
var2="foo bar"
if [[ $a == "foo bar" ]]; then
echo "ok"
fi
Result:
ok
For that, your code in BASH:
if [[ $output -ge 11 ]]; then
echo "CRITICAL: $output"
exit 2
elif [[ $output -ge 6 ]]; then
echo "WARNING: $output"
exit 1
else
echo "OK: $output"
exit 0
fi
I am writing a couple of bash scripts which I wish to call within another bash script but I can't seem to get these two examples online to work. It keeps telling me that there is an unexpected error near "r" and one near "mychoice" though it doesn't get resolved when I make the changes. The two classes are to generate a prime numbers test which if it works, I hope to be able to stress a cpu. the other class is just to dynamically select how long to run sar rather than having to hard code in sar 1 30 for example. Does anyone know what is wrong with these classes? Thanks in advance.
primetest class
#!/bin/bash
#
# primes.sh - find all prime numbers up to a certain number
# 2008 - Mike Golvach - eggi#comcast.net
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#
factorial () {
local factorial_count=$1
if [ "$factorial_count" -eq 0 ]
then
factorial_count=1
fi
for (( factor=$((factorial_count -1)); $factor >= 1; --factor ))
do
factorial_count=$(($factorial_count * $factor))
done
echo $factorial_count
}
prime_number () {
local prime=$1
p_minus_1=$(($prime - 1))
fact_p_minus_1=`factorial "$p_minus_1"`
fact_plus_1=$(($fact_p_minus_1 + 1))
echo $fact_plus_1
}
highest_number=$1
if [ -z $highest_number ]
then
echo
echo "Usage: $0 highestNumber"
echo
exit 1
fi
if [ $highest_number -eq 0 ]
then
echo
echo "Sorry. 0 is not a prime number"
echo
exit 0
elif [ $highest_number -eq 1 ]
then
echo
echo "Sorry. 0 and 1 are not prime numbers"
echo
exit 0
fi
echo "Generating Prime Numbers Up To $highest_number"
if [ $highest_number -eq 2 ]
then
echo
echo -n "2"
else
echo
echo -n "2 3 "
fi
count=4
while [ $count -le $highest_number ]
do
prime_return=`prime_number "$count"`
prime_test=$(($prime_return % count))
if [ $prime_test -eq 0 ]
then
echo -n "$count "
fi
count=$(($count + 1))
done
echo
echo
echo "All Set!"
echo
exit 0