4

I have a folder which contains some folders, these folder are moved very often so I made a script to see if they exist, and if not then create them. This is what I did to (which I though would) achieve it:

if [ ! -f "$DIR/0folder" ]
then
mkdir "$DIR/0folder"
fi

But, even if 0folder already exists, it still tries to make it which mkdir tells me. Like here;

mkdir: /Allfoldersgoeshere/subfolder/0folder: File exists

Why? It should just ignore it because it already exists?

  • 1
    Have you tried to replace -f by -d? – Cyrus Apr 7 '15 at 20:38
  • 3
    THe simpel answer is mkdir -p "$dir/0folder" It will create if it doesn't exist otherwise nothing happens. – Valentin Bajrami Apr 7 '15 at 20:56
  • @val0x00ff: That should be an answer – slebetman Apr 8 '15 at 0:50
12

The -f in your test is checking if FILE exists and is a regular file. What you need is -d to test if FILE exists and is a directory.

if [ ! -d "$DIR/0folder" ]
then
mkdir "$DIR/0folder"
fi

It is not mandatory to check if a directory exists though. According to the man page of mkdir we see the following

man mkdir | grep -A1 -- -p

   -p, --parents
          no error if existing, make parent directories as needed

However, if FILE exists and is a regular file mkdir -p will fail with

mkdir: /Allfoldersgoeshere/subfolder/0folder': Not a directory.  

In this scenario handling the file that is expected to be a directory will be necessary before directory creation.

  • Oh, so -f is for files and -d for directories? – DisplayName Apr 7 '15 at 20:39
  • 1
    Yes, man test will show the test options. – Timothy Martin Apr 7 '15 at 20:40
  • 3
    And if you don't care what sort of thing it is, you can use -e. – Mark Apr 7 '15 at 23:31
  • @val0x00ff - Thank you for adding the mkdir -p info. – Timothy Martin Apr 8 '15 at 18:30
3

From the manual (man bash) under CONDITIONAL EXPRESSIONS:

-f file
          True if file exists and is a regular file.

-d file
          True if file exists and is a directory.

So, to check for the existence of a directory (not a file)...

if [[ ! -d "$DIR/0folder" ]] ; then
    mkdir "$DIR/0folder"
fi
3

Neither -d or -f is useful here for robust tests - because they're just opposite sides of the same coin.

touch file; [ ! -d file ] && mkdir file
mkdir: cannot create directory ‘file’: File exists

See? Better would be [ -e ... ] || mkdir ... to check for existence, which would at least save on the error above, but even that has its issues - like race conditions or not creating parents as needed or unresolved symlinks.

if    [ ! -e "$DIR/0folder" ] && 
      [ ! -L "$DIR/0folder" ] 
then  mkdir -- "$DIR/0folder"
fi

...is closer but still racy and still assumes all parents exist as well.

Probably you could work out a sure test if you needed to, but you really don't. You can get atomic directory creation w/ mkdir -p and test its return. There aren't too many standard shell tools which offer atomic fs ops - it's best we take advantage of those that do.

  • +1 for presenting a more complete answer and explanation than mine. – Timothy Martin Apr 8 '15 at 16:59
2

Read the manual. The -p option will make a directory and intermediate directories as required if it doesn't exist or silently fail. Assuming that you are not processing thousands of files then you could just do mkdir -p "${DIR}/0folder or if you feel the need to test then

 [ -d "${DIR}/0folder" ] || mkdir -p "${DIR}/0folder"
  • 2
    The -d test before mkdir -p is rather useless. If it is useful to know whether or not a directory was created, just test mkdir exit status: 0 means a directory was created. That said. +1 for mkdir -p... to nullify the notification when exit status is non-zero, mkdir -p dir/dir 2>/dev/null – Peter.O Apr 8 '15 at 0:18
  • 1
    @Peter.O - possibly worse than useless - it implies the test is useful, but it is not. – mikeserv Apr 8 '15 at 17:19
1

You're doing: if the $DIR/0folder doesn't exist, make a directory with that name.

Just change -f (file) by -d (directory).

That should solve your problem, now you could be interested on some tips that people had given here but that is apart.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.