0

So I have this shell script that I think should run a given number of times, sleep then resume, and output the results to a log file

#!/bin/bash

log=/path/to/file/info.log
a=$(COMMAND1 | cut -d : -f 2)
b=$(COMMAND2 | grep VALUE| cut -c 7,8)

for i in {1..4}
 do
         echo "Test" $i  >> $log
         date >> $log
         echo $a >> $log
         echo "$((-113 + (($b * 2)))) VALUE" >> $log
         sleep 60
 done

When I run ps -ef | grep scriptname.sh it seems the script does run. Executes once then the PID is gone as if the run has completed.

I have tested the script and know that it is running and capturing the data I want. But I do not understand why its not incrementing and not sure why its ending earlier than expected.

info.log output sample

Test {1..4}
DATE IN UTC
EXPECTED VALUE OF a
EXPECTED VALUE OF b

Note that the output is literally "Test {1..4}" not "Test 1" "Test 2" Test 3" and so on, as I would expect.

I have run the script as ./scriptname.sh & and as /path/to/file/scriptname.sh &

I have read that there is a difference in running the script with sh and bash though I dont fully understand what effect that would have on the script. I am not a software person at all.

I have tried to run the script with nohup to keep it running in the background if I close the terminal. I also thought the & in the command was supposed to keep the script running in the background. Still it seems the script does not continue to run

I previously asked this question and it was closed, citing that it was similar to a post about the difference between sh and bash...but thats not my main question.

also echo "$BASH_VERSION" returns nothing, a blank line. echo "$-" returns smi, and I have no idea what that means. but bash --version returns:

BusyBox v1.17.1 (2019-11-26 10:41:00 PST) built-in shell (ash)
Enter 'help' for a list of built-in commands.

So my questions are:

  1. If running the script with sh - is that done with ./scriptname.sh & and running the script with bash is /path/to/file/scriptname.sh &...and if so what effect does that have on how the script code is processed? that is - is using sh or bash. I do not fully understand the difference between the two

  2. why does the script not continue to run when I close the terminal? This is my big concern. I would like to run this script hourly for a set period of time. Every time I try something and come back I get one instance in the log.

Antonio Petricca
  • 8,891
  • 5
  • 36
  • 74
mcv110
  • 13
  • 4
  • 3
    You're not running Bash, your `/bin/bash` points to ash, a minimal POSIX compliant shell. And ash does not support brace expansion; you have to use something like `for i in 1 2 3 4` instead. – Benjamin W. Sep 10 '21 at 14:30
  • @BenjaminW. is correct. You can also go `for i in $(seq 1 4)` if the number of repetitions needs to be dynamic, like `max=5; for i in $(seq 1 $max)` – Jeff Breadner Sep 10 '21 at 14:35
  • 1
    Answering your questions: 1) Per BenjaminW, you are running neither `sh` nor `bash`, as your system is replacing those commands with `ash` instead. This is the core of your issue. It doesn't matter if you use a relative or absolute path to call the script. 2) `ash` doesn't understand the `{1..4}` syntax, so it sees this as a single argument and runs once with that full "{1..4}" string instead of the numbers that you intend. Use the suggestions above, it will loop multiple times as you expect; if you launch it in the background with `&` it should continue to run after you log out. – Jeff Breadner Sep 10 '21 at 14:40
  • @BenjaminW. So all I would need to do to keep this script running is to change my 'for' statement to leave out the the curly brackets? so something like for 'i in 1 2' and so on, up to the number of times I want it to run? – mcv110 Sep 10 '21 at 14:42
  • That, or using `seq` as per Jeff's recommendation; `seq` is included with busybox. – Benjamin W. Sep 10 '21 at 14:53
  • well that seems to have done it, I'll have to let it run for a few hours to confirm but the output in the log is now `Test 1` not `Test {1..4}` Thanks for the input. one more question though, since the script is running with `ash` should i run the script `./scriptname &` or `/path/to/file/scriptname.sh &`? does that matter? – mcv110 Sep 10 '21 at 14:54
  • @JeffBreadner `seq` is not part of POSIX, either (though it may indeed be present). The fully POSIX-compliant solution is a `while` loop that explicitly initializes and increments `i`. – chepner Sep 11 '21 at 16:21
  • See also [Difference between sh and bash](https://stackoverflow.com/questions/5725296/difference-between-sh-and-bash) – tripleee Sep 11 '21 at 19:27

1 Answers1

0

Neither brace expansion nor seq are part of the POSIX specification. Use a while loop.

log=/path/to/file/info.log
a=$(COMMAND1 | cut -d : -f 2)
b=$(COMMAND2 | grep VALUE| cut -c 7,8)

i=1
while [ "$i" -le 4 ]; do
    printf 'Test %s\n' "$i"
    date
    printf '%s\n' "$a"
    printf '%s\n' "$((-113 + (($b * 2)))) VALUE"
    sleep 60 
    i=$((i+1))
done >> "$log"

(I suspect that you want to move the assignments to a and b inside the loop as well; right now, you are simply writing identical files to the log at each iteration.)

chepner
  • 497,756
  • 71
  • 530
  • 681