1

Loop does not work normally in git action.

My task.sh looks like this:

#!/bin/bash

range=100
number=$((RANDOM % range))

while [ "$i" -le "$number" ]; do
    echo "DATE: $1" >> date.txt
done

The result of the above code is:

./task.sh: 6: [: Illegal number:

The code below works fine.

echo "DATE: $1" >> date.txt

I tried the following, but it also gives an error.

#!/bin/bash

range=500
number=$((RANDOM % range))

for ((run=1; run <= number; run++)); do
    echo 'hello'
done

I'm curious how you can make a command like below work normally.

while (random(1-100)); do
     echo 'hello'
done

Best regards!

jthill
  • 55,082
  • 5
  • 77
  • 137
  • You never defined `i` in the original code, so `bash` is trying to execute `[ "" -le "10" ]` or the like. – chepner Nov 07 '21 at 12:37
  • @chepner Not necessarily. By default, `i` would be valued at 0 (or empty). Incrementing `i` is enough to initialize it to 1, 2, and so on. It would be cleaner, yes, but it does actually work as is. (see my script in my answer) – VonC Nov 07 '21 at 12:38
  • @VonC `[ i -le "$number" ]` would default `i` to 0, but `[` never sees the string `i`, only the empty string resulting from the expansion. – chepner Nov 07 '21 at 12:39
  • @chepner No matter, it still works. – VonC Nov 07 '21 at 12:40
  • What do you mean by "works"? The loop never executes, because `[ "" -le anything ]` is immediately false due to the error. – chepner Nov 07 '21 at 12:42
  • @chepner Agreed. I have edited the answer to make that clearer. – VonC Nov 07 '21 at 12:42
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/238959/discussion-between-vonc-and-chepner). – VonC Nov 07 '21 at 12:44
  • The `for` loop you tried looks fine; are you sure you are using `bash` to execute the script? Something like `sh task.sh` will ignore the `#!/bin/bash` and use whatever shell `sh` refers to, which in some Linux distributions is `dash`, not `bash`. – chepner Nov 07 '21 at 13:02

2 Answers2

3

It should work fine with:

while [[ "$i" -le "$number" ]]; do
      ^^                    ^^

This requires bash, but since your shebang is #!/bin/bash, your t.sh script will run with bash, no matter its '.sh' extension.

But in its current form, it would be an infinite loop.

You would need to add

i=$((i+1))

That would increment the $i variable, making "$i" -le "$number" work properly.

Initializing i to 0 is better/cleaner, but [[ "" -le "$number" ]] (on the first loop, still "works" (in that an empty string is consider "lower or equal" to an non-empty "$number" string, and remains in the loop)


That being said, the more correct form/usage for that script would be (using arithmetic comparison):

#!/bin/bash

range=100
number=$((RANDOM % range))
i=0

while (( i <= number )); do
    echo "DATE: ${i}" >> date.txt
    i=$((i+1))
done

Or, using a c-style loop

#!/bin/bash

range=100
number=$((RANDOM % range))

for ((i = 0 ; i < number ; i++)); do
    echo "DATE: ${i}" >> date.txt
done

All this assumes bash, but as seen here, since for (( ... )) syntax isn't POSIX, it would not work with Alpine Linux or other OS where sh links to ash (Almquist shell) or Dash.

In that latter case:

#!/bin/bash

range=100
number=$((RANDOM % range))

for i in $(seq 0 $number); do
    echo "DATE: ${i}" >> date.txt
done
chepner
  • 497,756
  • 71
  • 530
  • 681
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • The `[[` syntax is a bash extension so would require running with bash. The infinite loop is definitely a problem as well. :-) – torek Nov 07 '21 at 03:45
  • @torek `#!/bin/bash` on a Mac means... you are running with bash. Even if the extension is `.sh`. – VonC Nov 07 '21 at 12:23
  • `[[` isn't necessary, as long as you initialize `i` before (and modify it inside) the loop. – chepner Nov 07 '21 at 12:42
  • `[[ ... -le ... ]]` is something of an anti-pattern; either `[[ ... ]]` isn't available and you need to use `[ ... ]`, or it *is* available, which implies the much more readable `(( ... <= ... ))` is also available. – chepner Nov 07 '21 at 12:43
  • @VonC: good point, I didn't notice the `#!` line at all! – torek Nov 07 '21 at 12:46
  • @chepner `[[ ]]` is not an anti-pattern, when you are using bash: https://stackoverflow.com/a/56762558/6309 – VonC Nov 07 '21 at 12:49
  • @VonC I am referring specifically to its use in place of `(( ... ))`, which provides more traditional comparison operators for integers. `[[ ... ]]` is fine for string comparison and the various file operators. – chepner Nov 07 '21 at 12:52
  • @chepner arithmetic comparison, right. I have edited the answer to propose a more suitable version of the original script. – VonC Nov 07 '21 at 13:00
  • And finally, the C-style `for` loop would be preferable to a `while` loop. The example the OP gave looks fine; I suspect the script was somehow not being executed with `bash` in the first place. – chepner Nov 07 '21 at 13:01
  • @chepner It was executed with bash in the first place, at least according to its shebang, as commented above. – VonC Nov 07 '21 at 13:02
  • @VonC Assuming the OP didn't do something like `sh task.sh` to execute the script. – chepner Nov 07 '21 at 13:03
  • @chepner True. Just in case, I have added the non-bash version. – VonC Nov 07 '21 at 13:12
  • Please don't suggest `seq`. It's no more part of POSIX than `[[ ... ]]`, `((...))`, or `for ((...))`. It also has to generate the full range in advance, rather than simply incrementing a single value as needed. – chepner Nov 07 '21 at 13:18
2

You have two separate problems:

  1. You are running your script with sh, not bash
  2. You are not assigning i

For the first one, see Why does my Bash code fail when I run it with 'sh'?

For the second, set i=0 in your script before you try to compare $i as a number.

that other guy
  • 116,971
  • 11
  • 170
  • 194