Whenever I run the bash script I encounter this problem:
LRU.sh: line 121: syntax error near unexpected token `fi'
The script is:
#!/bin/bash
declare -i numOfPageRRef=0
declare -i numOfFrames=$1
declare -i a=0
declare -i k=0
declare -i c=0
declare -i q
declare -i c1=0
OIFS=$IFS
IFS=','
read line < Input2.csv
for val in $line
do
pageRef[$numOfPageRRef]=$val
((numOfPageRRef++))
done
#echo ${pageRef[#]}
q[$k]=${pageRef[$k]} #chck here
echo ${q[$k]}
((c++))
((k++))
for((i=1;i<numOfPageRRef;i++))
do
c1=0
for((j=0;j<numOfFrames;j++))
do
if (( ${pageRef[$i]} -ne ${q[$j]} ))
then
((c1++))
fi
done
if (( c1 -eq numOfFrames ))
then
((c++))
if (( k -lt numOfFrames )) ;then
q[$k]=${pageRef[$i]}
((k++))
for((j=0;j<numOfFrames;j++))
do
echo ${q[$j]}
done
else
for((r=0;r<numOfFrames;r++))
do
c2[r]=0
for((j=i-1;j<numOfPageRRef;j--))
do
if (( ${q[$r]} -ne ${p[$j]} ))
then
((c2[r]++))
else break
fi
done
done
for((r=0;r<numOfFrames;r++))
do
t4=${c2[r]}
b[$r]=$t4
for((r=0;r<numOfFrames;r++))
do
for((j=r;j<numOfFrames;j++))
do
if (( ${b[$r} -lt ${b[$j]} ))
then
t=${b[r]}
t2=${b[j]}
b[$r]=$t2
b[$j]=$t
fi
done
done
for((r=0;r<numOfFrames;r++))
do
if (( ${c2[$r]} -eq ${b[0]} ))
then
t3=${p[$i]}
q[$r]=$t3
fi
echo ${q[$r]}
done
#echo
fi
fi
done
echo "The no of page fault is $c"
Your error is because you missed a done closing statement, when i remade all the syntax in your code i was able to see it, its in the bottom. so here is your code without the error.
P.S
In the future please pay attention on the syntax, it makes big difference while reading the code.
OIFS=$IFS
IFS=','
read line < Input2.csv
for val in $line
do
pageRef[$numOfPageRRef]=$val
((numOfPageRRef++))
done
#echo ${pageRef[#]}
q[$k]=${pageRef[$k]} #check here
echo ${q[$k]}
((c++))
((k++))
for((i=1;i<numOfPageRRef;i++))
do
c1=0
for((j=0;j<numOfFrames;j++))
do
if (( ${pageRef[$i]} -ne ${q[$j]} ))
then
((c1++))
fi
done
if (( c1 -eq numOfFrames ))
then
((c++))
if (( k -lt numOfFrames ))
then
q[$k]=${pageRef[$i]}
((k++))
for((j=0;j<numOfFrames;j++))
do
echo ${q[$j]}
done
else
for((r=0;r<numOfFrames;r++))
do
c2[r]=0
for((j=i-1;j<numOfPageRRef;j--))
do
if (( ${q[$r]} -ne ${p[$j]} ))
then
((c2[r]++))
else break
fi
done
done
for((r=0;r<numOfFrames;r++))
do
t4=${c2[r]}
b[$r]=$t4
for((r=0;r<numOfFrames;r++))
do
for((j=r;j<numOfFrames;j++))
do
if (( ${b[$r]} -ne ${b[$j]} ))
then
t=${b[r]}
t2=${b[j]}
b[$r]=$t2
b[$j]=$t
fi
done
done
for((r=0;r<numOfFrames;r++))
do
if (( ${c2[$r]} -eq ${b[0]} ))
then
t3=${p[$i]}
q[$r]=$t3
fi
echo ${q[$r]}
done
done #Here You forgot the done!!!!!
fi
fi
done
echo "The no of page fault is $c"
Related
n=20
x=3
count=0
flag=0
i=1
declare -a arr[n+1]
for (( j=0;j<=n;j++ ))
do
arr+=(0)
done
#echo "${arr[#]}"
while [[ $count -ne $n ]]
do
if [[ $i -le $n ]]
then
if [[ ${arr[$i]} -eq '0' ]]
then
echo "Value is ${arr[$i]}"
#${arr[$(i-1)]}= (( ${arr[$i-1]++} ))
${arr[$i]}+=${arr[$i]}
echo " "
#echo -n "${arr[$i]}"
echo -n " $i"
count=$(( count+1 ))
i=$(( i+1+x ))
else
i=$(( i+1 ))
fi
else
i=$(( i-n ))
flag=$(( flag+1 ))
fi
done
echo " "
echo "No of round : $flag"
This is the whole code, I've tried to print numbers that follows this: n=20 is the number of elements and x=3 is the number that we have to avoid. For example,
20
3
1,5,9,13,17,2,6,10,14,18,3,7,11,15,19,4,8,12,16,20,
3
But, the problem is that my second if condition is not fulfilling, if ignores the condition. Above example is for the C++, but in bash script, 2nd if statement isn't working. This can be because syntax is wrong. So can you please help me to find the mistakes.
Output of the above code:
output
${arr[$i]}+=${arr[$i]}
This is incorrect. $ should not be used when you assign the value.
If you want to double the value, replace this string with the following:
arr[$i]=$(( ${arr[$i]} + ${arr[$i]} ))
Or what you want to do there?
This is the code:
sum=0
i=1
while [ $i -le $# ]
do
if [[ $i =~ ^[0-9]+$ ]];
then
sum=$(($sum+$(eval echo '$'$(eval echo ${i}))))
echo "$(eval echo '$'$(eval echo $i)) is number"
i=$((i+1))
else
echo "$(eval echo '$'$(eval echo $i)) is not a number"
i=$((i+1))
fi
done
echo "sum is $sum"
and this is the output when I try to distinguish b/w numbers and characters:
$ bash sumOfGivenNums.sh 3 4 3 a
3 is number
4 is number
3 is number
a is number
sum is 10
You've got a lot of really unnecessary code in your script; you almost never want to use the eval function. I would probably write something like this:
sum=0
for arg in "$#"; do
if [[ $arg =~ ^[0-9]+$ ]]; then
echo "$arg is a number"
(( sum += arg ))
else
echo "$arg is not a number."
fi
done
echo "sum is $sum"
Here is my script:
age=119
if [[$age -gt 99 ]]; then
age_3digits=$age
elif [[$age -gt 9]]; then
age_3digits=0$age
else
age_3digits=00$age
fi
z_grid=${age_3digits}Ma.grd
echo $z_grip
output: 00119Ma.grd
how come?? I am new to bash, thanks so much
You need a space after [[ and before ]]. Change to:
if [[ $age -gt 99 ]]; then
age_3digits=$age
elif [[ $age -gt 9 ]]; then
age_3digits=0$age
else
age_3digits=00$age
fi
It's also better to use arithmetic expressions because it makes your code more readable, like this:
if (( age > 99 )); then
age_3digits=$age
elif (( age > 9 )); then
age_3digits=0$age
else
age_3digits=00$age
fi
I'm writing a shell script
it works great, the only problem I have is that I want to avoid the possibility of using both options -d) and -x) at the same time when executing my command with my parameters in directories.
Could this be possible with a minimal change in my code?
#!/bin/bash
dir=$1
if [ $# -lt 1 ] ; then
echo "ERROR: no argument"
exit 1 # pas 0
else
case $2
in
-d)
mv $dir/ /tmp/
echo 'moving with -d'
;;
-x)
for f in "$dir"/*; do [[ -x $f ]] && mv "$f" /tmp; done
echo 'moving executables'
;;
*)
mv $dir/* /tmp/
echo 'no flag passed so moving all'
echo "mv $dir/* /tmp/"
;;
esac
fi
I would do it the other way: first extract options, then "if" it.
#!/bin/bash
dir=$1
shift
while [ $# -gt 0 ] ; do
case $1
in
-d)
D_OPTION_SELECTED=1
;;
-x)
X_OPTION_SELECTED=1
;;
esac
shift
done
help() {
echo "Usage $0 dir [-x or -d]";
}
if [[ "$dir" == "" ]]; then help; exit 1; fi
if [[ $D_OPTION_SELECTED -gt 0 && $X_OPTION_SELECTED -gt 0 ]]; then help; exit 1; fi
if [[ $D_OPTION_SELECTED -gt 0 ]]; then echo D selected; fi
if [[ $X_OPTION_SELECTED -gt 0 ]]; then echo X selected; fi
But please remember that the good rule is to allow options at first places. So the better version would be:
#!/bin/bash
while [ $# -gt 0 ] ; do
case $1
in
-d)
D_OPTION_SELECTED=1
;;
-x)
X_OPTION_SELECTED=1
;;
*)
dir=$1
;;
esac
shift
done
help() {
echo "Usage $0 [-x or -d] dir";
}
if [[ "$dir" == "" ]]; then help; exit 1; fi
if [[ $D_OPTION_SELECTED -gt 0 && $X_OPTION_SELECTED -gt 0 ]]; then help; exit 1; fi
if [[ $D_OPTION_SELECTED -gt 0 ]]; then echo D selected; fi
if [[ $X_OPTION_SELECTED -gt 0 ]]; then echo X selected; fi
echo dir=$dir
in bash I need to compare two float numbers, one which I define in the script and the other read as paramter, for that I do:
if [[ $aff -gt 0 ]]
then
a=b
echo "xxx "$aff
#echo $CX $CY $CZ $aff
fi
but I get the error:
[[: -309.585300: syntax error: invalid arithmetic operator (error token is ".585300")
What is wrong?
Thanks
Using bc instead of awk:
float1='0.43255'
float2='0.801222'
if [[ $(echo "if (${float1} > ${float2}) 1 else 0" | bc) -eq 1 ]]; then
echo "${float1} > ${float2}"
else
echo "${float1} <= ${float2}"
fi
use awk
#!/bin/bash
num1=0.3
num2=0.2
if [ -n "$num1" -a -n "$num2" ];then
result=$(awk -vn1="$num1" -vn2="$num2" 'BEGIN{print (n1>n2)?1:0 }')
echo $result
if [ "$result" -eq 1 ];then
echo "$num1 greater than $num2"
fi
fi
Both test (which is usually linked to as [)and the bash-builtin equivalent only support integer numbers.
Use bc to check the math
a="1.21231"
b="2.22454"
c=$(echo "$a < $b" | bc)
if [ $c = '1' ]; then
echo 'a is smaller than b'
else
echo 'a is larger than b'
fi
I would use awk for that:
e=2.718281828459045
pi=3.141592653589793
if [ "yes" = "$(echo | awk "($e <= $pi) { print \"yes\"; }")" ]; then
echo "lessthanorequal"
else
echo "larger"
fi
The simplest solution is this:
f1=0.45
f2=0.33
if [[ $f1 > $f2 ]] ; then echo "f1 is greater then f2"; fi
which (on OSX) outputs:
f1 is greater then f2
Here's another example combining floating point and integer arithmetic (you need the great little perl script calc.pl that you can download from here):
dateDiff=1.9864
nObs=3
i=1
while [[ $dateDiff > 0 ]] && [ $i -le $nObs ]
do
echo "$dateDiff > 0"
dateDiff=`calc.pl $dateDiff-0.224`
i=$((i+1))
done
Which outputs
1.9864 > 0
1.7624 > 0
1.5384 > 0