bash script to iterate from middle of a list

Viewed 40

I have a bash script that iterates over a folder of sql scripts. I want it to run intelligently when the script encounters an error. I don't want to run a step twice.

for a in $files_list; do
 command 1
 command 2 
.
.
done

If 1,2,3,4,5 are the files to be executed and script exits at step 3 with some error. In next execution, I want to run from step 3 only. I have a variable in place for detecting at which step the script exited. I am stuck at starting the iteration from that variable. Is it something that can be done? Any suggestion is accepted. I'm open to change my logic as well.

1 Answers

Didn't really spend much time but Let's say all the commands you want to execute are stored in a file test.txt

test.txt

ls
cal
du
d
date
ls

The following bash script takes two arguments filename where the commands are stored and the checkpoint from where it needs to start.

test.sh

## Function to read a file line by line

checkpoint=$2
filename=$1
checkpointReached=false

read_file_line_by_line() {
    local file="$1"
    while IFS= read -r line
    do
        if [ $checkpointReached == "false" ] && [ "$line" != "$checkpoint" ] ; then
            echo "...... Finding checkpoint....... current line is $line"
        fi
        if [ "$line" == "$checkpoint" ]; then
        echo "        *************************************************
                Checkpoint reached. Commands after checkpoint
        *****************************************************"        
            checkpointReached=true
            continue
        fi

        if $checkpointReached; then
            echo "        $line"
            execute_command $line
        fi
    done < "$file"
}

function execute_command() {
    local command="$1"
    echo "   Executing ..........     $command"
    if eval $command; then
        echo "   Command executed successfully"
    else
        echo "   Command failed. Exiting........"
        echo "   Please note the new checkpoint.... $command"
        exit 1
    fi
}

read_file_line_by_line "$filename"

Let's run it the first time, the checkpoint is the first command i.e. ls and its expected to fail at d which is invalid command

╰─ bash test.sh text.txt "ls"
        *************************************************
                Checkpoint reached. Commands after checkpoint
        *****************************************************
   Executing ..........     ls
test.sh         test.yaml       text.txt
   Command executed successfully
        du
   Executing ..........     du
24      .
   Command executed successfully
        d
   Executing ..........     d
test.sh: line 33: d: command not found
   Command failed. Exiting........
   Please note the new checkpoint.... d

Now we know the checkpoint. So we pass it along. Assuming that d is fixed now, we change it with echo for the sake of the script. In your case the script d would be fixed.

╰─ bash test.sh text.txt "echo"
...... Finding checkpoint....... current line is ls
...... Finding checkpoint....... current line is du
        *************************************************
                Checkpoint reached. Commands after checkpoint
        *****************************************************
   Executing ..........     echo

   Command executed successfully
        date
   Executing ..........     date
Mon Sep 12 14:50:44 +04 2022
   Command executed successfully

Let me know if this helps.

Related