Home > Software design >  In zsh how do you make a loop that when the command FAILS, it retries the same command with new argu
In zsh how do you make a loop that when the command FAILS, it retries the same command with new argu

Time:04-10

Some context on why I'm asking this question. I'm currently screwing around in python trying stuff out and I want to utilize the os.system() command to try different potential wifi passwords from a dictionary text file I have until it succeeds. I've attempted using python itself to look for errors using TRY/EXCEPT but I'm not experienced enough to know how to look for errors in another resource and dictate actions based on that. So at the time I THOUGHT the most simple method is to say the following:

for current_pass in PotentialPasswords:
    os.system('networksetup -setairportnetwork en0 {} "{}"'.format(ssid, current_pass))

Of course this is awful and caused lots of issues. I tried several variations on this until it dawned on me that zsh has looping capabilities itself and so right now I'm looking at if it is possible to effectively tell zsh to execute a command, and if that command fails, try that same command again but with new arguments, UNTIL the command succeeds, at which case I want the loop to end.

for x in pass1 pass2 pass3 pass4; do networksetup -setairportnetwork en0 NETWORK_NAME $x; done

I know the above does not work, but I hope that I'm at least on the right track. Any advice or guidance on how to accomplish my goal would be infinitely appreciated!

CodePudding user response:

#!/bin/bash

# Simulate an external command that randomly fails
function external_command {
    if [ $[ $RANDOM % $1 ] -eq 0 ] ; then
        echo "succeed"
        return 0
    else
        echo "failed"
        return 1
    fi
}

# Iterate over your predefined tests
for i in 2 3 4 5 ; do
    # Retry logic
    while
        echo -n "Trying external_command $i... "
        # Call the external command
        external_command $i
        # $? is the return code, 0 if successful
        [ $? -ne 0 ]
    do true ; done
done

Which gives an output such as this:

Trying external_command 2... succeed
Trying external_command 3... failed
Trying external_command 3... succeed
Trying external_command 4... failed
Trying external_command 4... succeed
Trying external_command 5... failed
Trying external_command 5... failed
Trying external_command 5... failed
Trying external_command 5... failed
Trying external_command 5... failed
Trying external_command 5... failed
Trying external_command 5... failed
Trying external_command 5... succeed

I borrowed the idea of the do..while loop from here.

The solution should work in bash/zsh.

  • Related