2

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?

Roland
  • 7,525
  • 13
  • 61
  • 124

2 Answers2

3

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.

tripleee
  • 175,061
  • 34
  • 275
  • 318
2

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
Jetchisel
  • 7,493
  • 2
  • 19
  • 18
  • Thanks, still I would like to know what would be the best practice in case I ever need several commands in the condition. – Roland Feb 20 '20 at 10:57