Hi I want to write and empty body loop. I just want the loop counter to increment so I want the cpu to stay busy without any IO operation. Here is what I have written but it gives me an error:
#!/bin/bash
for (( i = 0 ; i <= 1000000; i++ ))
do
done
root#ubuntu:~# ./forLoop
./forLoop: line 4: syntax error near unexpected token `done'
./forLoop: line 4: `done'
You must specify at least one command in a loop body.
The best command for such a purposes is a colon :, commonly used as a no-op shell command.
You could put a no op command inside the loop like true or false (do nothing successfully or unsuccessfully respectively).
This will be a tight loop and will burn CPU. Unless you want to warm up your computer on a cold morning, you can simply say i=1000000 and have the same effect as the loop.
What is it that you're trying to achieve?
#!/bin/bash
let i=0
while [[ $i -le 1000000 ]]; do
let i++
done
You could use sleep x if you want to delay for x number of seconds.
Related
I'm running an infinite while loop in bash that has a counting element to it.
while :
do
#stuff including counting
trap break int
done
This works as I would like for the most part. When I hit Ctrl+C, the loop stops, but the script continues. However, the loop stops in the middle of the loop which means that the final count is inaccurate.
Is there a way to make this loop break at the very end?
Instead of executing break you can set a flag and break the loop at a designated location when the flag is set. Note that in a loop the loop head can also be seen as the very end of the loop.
state=run
trap 'state=end' int
while [ "$state" = run ]
do
# stuff
done
If you want to break somewhere in the middle use
state=run
trap 'state=end' int
while :
do
# stuff
[ "$state" = end ] && break
# more stuff
done
You can test the behavior quiet nicely by replacing # stuff with for i in {1..20}; do printf .; sleep 0.1; done; echo:
As we can see in the clip above, the outer loop finishes its current iteration (# stuff) until the very end.
I have a problem with the done.
It says I have some typo error but I can't figure what's wrong at all.
Here is the code:
#./bin/bash
until [$err == 0];
do
java -Xms512m -Xmx512m -cp lib/*:lib/uMad/*:mysql-connector-java-5.1.15-bin.jar:l2jfrozen-core.jar com.l2jfrozen.gameserver.GameServer
err=$?
sleep 5
done
Your shebang line is wrong. #./bin/bash will not execute bash.
It should read #!/bin/bash. You are probably using a shell other than bash to invoke this script.
Also, beware that the [$err == 0] line expands the value of $err, which is probably an empty string, unless it has been exported. If it's empty, this will result in an error, because Bash will be interpreting [ == 0].
The safest approach is this:
unset err
until [ "$err" == "0" ];
do
# etc...
done
From my experience when working with brackets and if loops, you need proper spacing and double, not single brackets. There needs to be space on each side of the double brackets with the exception of the semi-colon. Here is an example block:
#!/bin/bash
err=5
until [[ $err == 0 ]]; do
((err-=1));
echo -e "$err\n";
sleep 3
done
I do not see why the same would not apply to a do until loop.
You're probably aware but your heading has a period in it instead of a shebang.
#./bin/bash
I am using Konsole on kubuntu 14.04.
I want to take arguments to this shell-script, and pass it to a command. The code is basically an infinite loop, and I want one of the arguments to the inner command to be increased once every 3 iterations of the loop. Ignoring the actual details, here's a gist of my code:
#!/bin/bash
ct=0
begin=$1
while :
do
echo "give: $begin as argument to the command"
#actual command
ct=$((ct+1))
if [ $ct%3==0 ]; then
begin=$(($begin+1))
fi
done
I am expecting the begin variable to be increased every 3 iterations, but it is increasing in the every iteration of the loop. What am I doing wrong?
You want to test with
if [ $(expr $cr % 3) = 0 ]; then ...
because this
[ $ct%3==0 ]
tests whether the string $ct%3==0, after parameter substitution, is not empty. A good way for understanding this is reading the manual for test and look at the semantics when it is given 1, 2, 3 or more arguments. In your original script, it only sees one argument, in mine it sees three. White space is very important in the shell. :-)
In BASH you can completely utilize ((...)) and refactor your script like this:
#!/bin/bash
ct=0
begin="$1"
while :
do
echo "give: $begin as argument to the command"
#actual command
(( ct++ % 3 == 0)) && (( begin++ ))
done
I have two arrays that I want to loop in. I construct those properly and before going into for loop, I do echo them to be sure everything is ok with arrays.
But when I run the script, it outputs an error:
l<=: syntax error: operand expected (error token is "<="
I consulted the mighty Google and I understood it suffers from the lack of the second variable, but I mentioned earlier I do echo the values and everything seems to be OK. Here is the snippet..
#!/bin/bash
k=0
#this loop is just for being sure array is loaded
while [[ $k -le ${#hitEnd[#]} ]]
do
echo "hitEnd is: ${hitEnd[k]} and hitStart is: ${hitStart[k]}"
# here outputs the values correct
k=$((k+1))
done
k=0
for ((l=${hitStart[k]};l<=${hitEnd[k]};l++)) ; do //this is error line..
let array[l]++
k=$((k+1))
done
The variables in the for loop are echoed correctly but for loop won't work.. where am I wrong?
#
as gniourf_gniourf answered:
"... At some point, k will reach the value ${#hitEnd[#]}, and this is
exactly when hitEnd[k] is not defined and expands to an empty string!
Bang!"
meaning error output is displayed not at the beginning of the loop, but when k has a greater value than array's indices, pointing an index that array does not include...
That's because at some point ${hitEnd[k]} expands to nothing (it is undefined). I get the same error with ((l<=)). You should write your for loop as:
k=0
for ((l=${hitStart[0]};k<${#hitEnd[#]} && l<=${hitEnd[k]};l++)); do
so as to always have an index k that corresponds to a defined field in the array ${hitEnd[#]}.
Also, instead of
k=$((k+1))
you can just write
((++k))
Done!
Your script revised using better modern bash practice:
#!/bin/bash
k=0
#this loop is just for being sure array is loaded
while ((k<=${#hitEnd[#]})); do
echo "hitEnd is: ${hitEnd[k]} and hitStart is: ${hitStart[k]}"
# here outputs the values correct
((++k))
done
k=0
for ((l=hitStart[0];k<${#hitEnd[#]} && l<=hitEnd[k];++l)); do
((++array[l]))
((++k))
done
Now, I'm not too sure the for loop does exactly what you want it to... Don't you mean this instead?
#!/bin/bash
# define arrays hitStart[#] and hitEnd[#]...
# define array array[#]
#this loop is just for being sure array is loaded
for ((k=0;k<${#hitEnd[#]};++k)); do
echo "hitEnd is: ${hitEnd[k]} and hitStart is: ${hitStart[k]}"
# here outputs the values correct
((++k))
done
for ((k=0;k<${#hitEnd[#]};++k)); do
for ((l=hitStart[k];l<=hitEnd[k];++l)); do
((++array[l]))
done
done
A bit bandaid-y, but you rewrite your for-loop into a while loop:
l="${hitStart[k]}"
while [[ "$l" -le "${hitEnd[k]}" ]]; do
let array[l]++
k=$((k+1))
l=$((l+1))
done
I'm trying to do something like these:
while[$read!="0"];
In this program
#!/bin/sh
i=0
cont=0
while[$read!="0"]; do
read number
cont=`expr $cont + $number`
i++
done
cont=`expr $cont / $i -1`
echo
I want to stop suming the entries when I give it a 0
tnx
The variable you're reading into is $number, so reference that rather than $read in your loop.
Whitespace is significant, so make sure to include spaces before, after, and between all of the items in your loop. (Confusingly, you must not include spaces in an assignment statement like i=0. i = 0 is wrong.)
For good measure, use double quotes around the variable. That's a good practice so that if the user hits enter without typing a number your script doesn't barf on the empty string.
while [ "$number" != "0" ]; do
Also, your i++ isn't right. There are various ways to write that, the simplest being:
let i++
In this, an infinite loop would be appropriate, since you know the condition on which you want to (hint) break out of the loop. The way to get an infinite loop in sh is: while true; do ...; done
Also, read has a -p option that lets you have a prompt (so you know what you're being asked to enter): read -p "Enter a number: " number