Roland
Roland

Reputation: 7853

How to execute multiple commands in the while loop condition?

I want to create a directory with increasing numbers every time I run the script. My current solution is:

COUNTER=1
while mkdir $COUNTER; (( $? != 0 ))
do
     COUNTER=$((COUNTER + 1)) 
done

Is separating the commands in the while condition with a ;(semicolon) the best practice?

Upvotes: 2

Views: 2017

Answers (2)

Jetchisel
Jetchisel

Reputation: 7781

You don't need to test the exit status, just check if the directory exists already and increment. Here is one way

#!/usr/bin/env bash

counter=1
while [[ -e $counter ]]; do
  ((counter++))
done


if ! mkdir "$counter"; then  ##: mkdir failed
  echo failed                ##: execute this code
fi

POSIX sh shell.

#!/usr/bin/env sh

counter=1
while [ -e "$counter" ]; do
  counter=$((counter+1))
done

if ! mkdir "$counter"; then  ##: If mkdir failed
  echo failed                ##: Execute this code
fi
  • The bang ! negates the exit status of mkdir.

  • See help test | grep '^[[:blank:]]*!'

Well if you're just going to negate the exit status of mkdir inside the while loop then you might as well use until, which is the opposite of while

counter=1
until mkdir "$COUNTER"; do
  :
  COUNTER=$((COUNTER + 1))
done

Upvotes: 2

tripleee
tripleee

Reputation: 189307

The very purpose of while and the shell's other control statements is to run a command and examine its exit code. You can use ! to negate the exit code.

while ! mkdir "$COUNTER"
do
     COUNTER=$((COUNTER + 1)) 
done

Notice also the quoting; see further Why is testing "$?" to see if a command succeeded or not, an anti-pattern?

As such, if you want two commands to run and only care about the exit code from the second, a semicolon is the correct separator. Often, you want both commands to succeed; then, && is the correct separator to use.

Upvotes: 3

Related Questions