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?

1
  • What are you trying to achieve/do? create directories which is what your code does and what else? Commented Feb 20, 2020 at 11:02

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

Comments

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

1 Comment

Thanks, still I would like to know what would be the best practice in case I ever need several commands in the condition.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.