Integer Expression Expected : Bash - bash

I read on stack overflow that we need quotes here and added quotes, but it ddn't helped.
array_length=${fileNames[#]}
COUNTER=0
while [ "$COUNTER" -lt "$array_length" ]; do
I get the error still. Please help. Completely new to bash

array_length=${fileNames[#]}
should have been
array_length=${#fileNames[#]}
For the expected behaviour, your while loop should be:
while [ "$COUNTER" -lt "$array_length" ]
do
.
#do something
.
((COUNTER++)) # Equivalent to COUNTER=COUNTER+1
done
${fileNames[#]} expands to the whole array while prefixing it with # gives you the number of elements.
Sidenotes:
1. Don't forget to increment COUNTER inside while loop.
2. Try avoiding capitalized variables like COUNTER as they are usually reserved for the system.

Related

Get variable outside while loop shell script

I would like the get the content of variable outside the while loop using shell script
For example:
::
count = 5
while [ #count -gt 0]; do
a=3
b=4
if ( a > b)
result = "UP"
else
result = "DOWN"
fi
count=$[ $count - 1]
done
echo $result
$result appears empty every time!
I just want the content of result outside the loop.
Can anyone help on this issue! I know that the variable inseide the loop is executed in sub-shell, but I tried several tips and doesn't works!
Thanks in avdance
Wow you have a huge number of syntax errors in your short script. I have detailed them in the comments below as well as adjusted where the variables are declared to make the loop do something, e.g.
#!/bin/sh
count=5 ## no spaces aroung " = "
a=3 ## a & b never change in loop
b=4
while [ "$count" -gt 0 ]; do ## always quote variables in [ .. ], spaces required
if ((a > b)); then ## there are two ((..)) in arithmetic comparison
result="UP" ## NO spaces around " = "
else
result="DOWN" ## ditto
fi
printf "%d %s\n" "$count" "$result" ## some output helps
count=$((count - 1)) ## use arithmetic ((..)), no $ required inside
((a++)) ## increment a to make it iteresting.
done
First, in shell there is no spaces allowed around the '=' sign during assignments. When using [ .. ] you must have a space after [ and before ], and always quote your variables inside. The quoting isn't required with bash [[ ... ]] or with the arithmetic comparison ((..)).
Every if and elif must be followed by a then. Every for or while must be followed by a do.
When using the arithmetic operator ((..)) (either for an arithmetic operation or comparison) there are two parens required. You can also use the increment and decrement operators ++ and --, e.g. ((a++)) to increment/decrement values within, but it you are assigning the result you must preceded the opening (( with the $, e.g. $((count - 1))
Example Use/Output
$ sh count.sh
5 DOWN
4 DOWN
3 UP
2 UP
1 UP
I think that accounts for most of the syntax issues. If you have further questions, please drop a comment below.

How can i fix the bad substitution?

I got loc_list0,1,2,3,
and i try to do it efficiently and type
b=0
while [ $b -lt 4 ]
do
grep -c "${loc_list$b[0]}" Record$b.txt
done
It says Bad Substitution on ${loc_list$b[0]}, but ok for Record$b. What is the reason behind? I am new to bash shell can anyone tell me how to fix it instead of writing duplicate codes.
Thanks man!
But another problems come when i want to use two varibales for iteration
thanks man, how about i got two variables
b and c which works as counting numbers of iteration
such that:
b=0
c=0
while [ $b -lt 5 ]
do
temp_length=( "${loc_list$b[#]}" )
while [ $c -lt ${#temp_length[#]} ]
do
...
c=$((c+1))
done
...
b=$((b+1))
done
how to fix the bad substitution this time?
You need to use indirect parameter substitution. With arrays, the index you want is considered part of the name.
name=loc_list$b[0]
grep -c "${!name}" Record$b.txt
Record$b.txt works because it is a simple string concatenation, Record + $b + .txt. You aren't try to further expand the result.

Multiple If Statements in Bash Script

I am trying to make a bash script with the output based on the input.
My code looks like this:
#!/bin/bash
echo "Letter:"
read a
if a=3
then
echo "LOL"
fi
if a=4
then
echo "ROFL"
fi
But when I enter 3 or 4, I get both LOL and ROFL.
Is there a way for me to get LOL for 3 and ROFL for 4?
Sorry if I'm using incorrect terms and stuff, I'm new to bash scripting.
In bash, a=3 is an assignment, not a test. Use, e.g.:
if [ "$a" = 3 ]
Inside [...], the equal sign tests for string (character) equality. If you want to test for numeric value instead, then use '-eq` as in:
if [ "$a" -eq 3 ]
The quotes around "$a" above are necessary to avoid an "operator" error when a is empty.
bash also offers a conditional expressions that begin with [[ and have a different format. Many like the [[ format better (it avoids, for example, the quote issue mentioned above) but the cost is loss of compatibility with other shells. In particular, note that dash, which is the default shell (/bin/sh) for scripts under Debian-derived distributions, does not have [[.
Bash thinks you're trying to assign a variable by saying a=3. You can do the following to fix this:
Use the = operator whilst referencing the variable with a $, like so: if [[ $a = 3 ]]
Use the -eq operator, which is special and doesn't require you to reference the variable with a $, but may not be compatible with all sh-derived shells: if [[ a -eq 3 ]]. If you wish to use -eq without Bash reference the variable: if [[ $a -eq 3 ]]
Note:
The double square brackets [[ ... ]] are a preferred format with specifically Bash conditionals. [ ... ] is good with any sh-derived shell (zsh, tcsh, etc).
if a=3 will assign value 3 to variable a
unless a is readonly variable, if a=3 always returns TRUE
same for if a=4
To compare variable a with a value, you can do this if [ $a = 3 ]
so the script should change to
#!/bin/bash
echo "Letter:"
read a
if [ $a = 3 ]
then
echo "LOL"
fi
if [ $a = 4 ]
then
echo "ROFL"
fi
Since a is read from user input, there is possibility user key in:
non numeric value
a string with empty space
nothing, user may just press Enter key
so a safer way to check is:
if [ "x$a" = "x3" ]

Removing files in Unix using bash

I'm trying to delete a large amount of files from my computer, and I'm trying to write a bash script to do so using the rm command. What I want to know is how to do equality in bash, and why my code (posted below) won't compile. Thank you for your help!
#!/bin/bash
# int-or-string.sh
b="0000"
c="linorm"
f=500
e1=2
e2=20
e3=200
e4=2000
for i in {0..10000}
do
a=$(($f*$i))
if ["$i" -eq "$e1"]
then
b="000"
echo $b$
fi
if ["$i" -eq "$e2"]
then
b='00'
fi
if ["$i" -eq "$e3"]
then
b='0'
fi
if ["$i" -eq "$e4"]
then
b =''
fi
if [bash$ expr "$i" % "$e3$ -ne 0]
then
d = $b$c$a
rm d
fi
done
Shell scripts aren't compiled at all.
You need spaces after your [ and before your ].
if [ "$i" -eq "$e1" ]
There's an errant bash$ in there you probably don't want at all. It should probably be a $() operator:
if [ $(expr "$i" % "$e3") -ne 0 ]
You can't have spaces around the = in bash. For example, change b ='' to b='' and d = $b$c$a to d=$b$c$a.
echo $b$ looks like it should be echo $b.
Shell script does not compile it is a scripting language.
Try to fix this line :
if [bash$ expr "$i" % "$e3$ -ne 0]
Make it like below :
if [ $(expr "$i" % "$e3$") -ne 0 ]
You need spaces around the square brackets. The [ is actually a command, and like all commands needs to be delineated by white space.
When you set values for variables in shell, you do not put spaces around the equals signs.
Use quotation marks when doing comparisons and setting values to help delineate your values.
What happens if none of the if conditions are true, and $b isn't set.
What is the logic behind this code. It seems to be a bunch of random stuff. You're incrementing $ from 1 to 10000, but only setting the value of $b on only four of those values. Every 200 steps, you delete a file, but $b may or may not be set even though it's part of the file name.
Did you write this program yourself? Did you try to run it? What errors were you getting? Did you look at the lines referenced by those errors. It looks like you included the bash$ prompt as part of the command.
There were plenty of errors, and I've cleaned most of them up. The cleaned up code is posted below, but it still doesn't mean it will do what you want. All you said is you want to delete "a large amount of files" on your computer, but gave no other criteria. You also said "What I want to know is how to do equality in bash" which is not the question you stated in you header.
Here's the code. Note the changes, and it might lead to whatever answer you were looking for.
#!/bin/bash
# int-or-string.sh
b="0000"
c="linorm"
f=500
e1=2
e2=20
e3=200
e4=2000
for i in {0..10000}
do
a=$(($f*$i))
if [ "$i" -eq "$e1" ]
then
b="000"
elif [ "$i" -eq "$e2" ]
then
b='00'
elif [ "$i" -eq "$e3" ]
then
b='0'
elif [ "$i" -eq "$e4" ]
then
b=''
fi
if ! $(($i % $e3))
then
d="$b$c$a"
rm "$d"
fi
done
ERRORS:
Spaces around the [ and ]
The rm "$d" command was originallyrm dwhich would just remove a file namedd`.
if/then statement converted to if/else if.
Rewrote [ $(expr "$1" % "$e3") -ne 0 ].
No need for expr since BASH has $((..)) syntax.
No need for test command ([) since if automatically evaluates zero to true and non-zero to false.
Added quotes.

No output from script

I've edited my script, and get no more errors, however, the script is not executing to the Minecraft server, no announcement attempts are made at all for that matter. I'm rally puzzled. It's as if it's not running at all like the server is not running, but it is, and should be matching "is running" from the status command.
and code is:
#!/bin/bash
checkServer=$(/etc/init.d/minecraft status);
cd /.smc;
# Is the server even running?
if [ checkServer = *"is running"* ];
then
# No count file? Create it.
if [ ! -f /.smc/lastAnnouncement.txt ];
then
echo 0 < /.smc/lastAnnouncement.txt;
fi
# Load count
lastAnn=$(cat /.smc/lastAnnouncement.txt);
# ANNOUNCEMENTS
announcement[0]='Dont forget to check out http://fb.com/pyrexiacraftfans for news and updates';
announcement[1]='Use our Facebook page to request land protection! Visit http://fb.com/pyrexiacraftfans';
# Should we restart announcement que?
if lastAnn == ${#announcement[#]}+1;
then
echo 0 < /.smc/lastAnnouncement.txt;
fi
# Send announcement
sendAnnouncement=$(/etc/init.d/minecraft command say announcement[lastAnn]);
# Next announcement count
lastAnn=$((lastAnn+1));
# Write next announacment count
echo lastAnn < /.smc/lastAnnouncement.txt;
fi
There are multiple issues with your script, ranging from useless semicolons to bad logic. The list of issues is so long that it's easier to post a corrected script than point out the issues (the other answers don't even come close to listing all the errors).
The corrected script is:
#!/bin/bash
checkServer=$(/etc/init.d/minecraft status)
cd /.smc
# Is the server even running?
if [[ $checkServer =~ "is running" ]]; then
# No count file? Create it.
if [ ! -f /.smc/lastAnnouncement.txt ]; then
echo 0 > /.smc/lastAnnouncement.txt
fi
# Load count
lastAnn=$(cat /.smc/lastAnnouncement.txt)
# ANNOUNCEMENTS
announcement[0]='Dont forget to check out http://fb.com/pyrexiacraftfans for news and updates'
announcement[1]='Use our Facebook page to request land protection! Visit http://fb.com/pyrexiacraftfans'
# Send announcement
sendAnnouncement=$(/etc/init.d/minecraft command say ${announcement[$lastAnn]})
# Next announcement count
((++lastAnn))
# Write next announacment count
# Should we restart announcement que?
if [[ $lastAnn -gt ${#announcement[#]} ]]; then
echo 0 > /.smc/lastAnnouncement.txt
else
echo $lastAnn > /.smc/lastAnnouncement.txt
fi
fi
The issues with your script (leaving aside the excess semicolons which don't hurt, just needless disk space wastage):
missing $ before variable name
Incorrect string comparison. Use =~ instead of ==, [[ instead of [, and remove * from both sides of the string *"is running"*
if [ checkServer == *"is running"* ]
Wrong redirection. you want to write to file, so >, not <. This is multiple times.
echo 0 < /.smc/lastAnnouncement.txt;
echo 0 < /.smc/lastAnnouncement.txt;
Variable names missing $ and wrong redirection
echo lastAnn < /.smc/lastAnnouncement.txt;
Easier increment with ((++lastAnn)). Also this is invalid shell, as arithmetic needs expr command or ((...)) builtin
lastAnn=$lastAnn+1;
Missing $ in variable name. Missing test , [ or [[. Missing expr or $((..)) for addition of 1. -eq should be used instead of == for number equality. Logically this should use -gt to test against last index and +1 is not required.
if lastAnn == ${#announcement[#]}+1;
I won't go into the fact that the logic of writing the message queue index was incorrect, and would never loop back to 0.
However, you did a wonderful job of trying to write a script. Many people don't even try.
Edit : I missed out a {} on the array variable usage on line 21 of the script above. Fixed.
Try:
if [ checkServer = *"is running"* ];
(Yes single equals sign)
There are many errors:
First,
if [[ $checkserver == *"is running"* ]]
Using double [[...]] and a variable reference is $checkserver.
Then,
sendAnnouncement=$(
Without space.
Also,
if [ $lastAnn == $((${#announcement[#]}+1)) ]
Probably more...
I believe your script has quite a few syntax error.
i.e. there is a problem in this line:
sendAnnouncement = $(/etc/init.d/minecraft command say $announcement[$lastAnn]);
Replace it with this:
sendAnnouncement=$(/etc/init.d/minecraft command say $announcement[$lastAnn])
bash (and other shells) doesn't allow spaces before and after the assignment operator =
Also this line:
lastAnn=$lastAnn+1;
should be replaced with:
lastAnn=$((lastAnn+1))

Resources