0

I've created a simple script to check if a folder exists and if not to create it. The script that follow

#!/bin/bash 
PATH=~/Dropbox/Web_Development/
FOLDER=Test

if [ ! -d $PATH$FOLDER ] 
then
    echo $PATH$FOLDER 'not exists'
    /bin/mkdir $PATH$FOLDER
    echo $PATH$FOLDER 'has been created'
fi

works only if the mkdir command is preceded by /bin/. Failing in that, bash env output the error message "command cannot be found".

I though this could have been related to the system $PATH variable, but it looks regular (to me) and the output is as following:

 /Library/Frameworks/Python.framework/Versions/2.7/bin:/bin:/usr/local/bin:/usr/bin:/sbin:/usr/local/sbin:/usr/sbin

I'm not sure whether the order with the different bin folders have been listed make any difference, but the /bin one (where the mkdir on my OSX Maverick) seems to reside is there hence I would expect bash to being able to execute this.

In fact, if I call the bash command from terminal, by typing just mkdir bash output the help string to suggest me how the mkdir command should be used. This suggests me that at a first instance bash is able to recognise the $PATH variable.

So what could be the cause? Is there any relation between the opening statement at the top of my .sh - #!/bin/bash - file and the "default" folder?

Thanks

Andrea Moro
  • 676
  • 2
  • 9
  • 20

2 Answers2

4

Yeah, sometimes it is a bad idea to use capital letters for constant variables, because there are some default ones using the same convention. You can see some of the default variables here (Scroll to Special Parameters and Variables section). So it is better to use long names if you don't want to get any clashes.
Another thing to note is that you're trying to replicate mkdir -p functionality, which creates a folder if it does not exist (also it does create all of the parents, which is what you need in most cases)
One more thing - you always have to quote variables, otherwise they get expanded. This may lead to some serious problems. Imagine that

fileToRemove='*'
rm $fileToRemove

This code will remove all files in the current folder, not a file named * as you might expect.
One more thing, you should separate path from a folder with /. Like this "$MY_PATH/$MY_FOLDER". That should be done in case you forget to include / character in your path variable. It does not hurt to have two slashes, that means that /home/////////user/// folder is exactly the same /home/user/ folder.
Sometimes it is tricky to get ~ working, so using $HOME is a bit safer and more readable anyway.

So here is your modified script:

#!/bin/bash 
MY_PATH="$HOME/Dropbox/Web_Development/"
MY_FOLDER='Test'

mkdir -p "$MY_PATH/$MY_FOLDER"
Aleks-Daniel Jakimenko-A.
  • 10,335
  • 3
  • 41
  • 39
  • I'll withdraw my answer, you read the rest of the script and understood the meaning of "PATH" for the OP ^^. +1 – Olivier Dulac Dec 28 '13 at 14:10
  • It seems the previous answer for some reason has gone, so please don't remove this one. Thanks for your input anyway. That said I've a challenge: my script will be run from a third part system (Vagrant) that runs the script as a root user. Therefore by using $HOME, this will correspond to Root's home and not mine. Is there anyway to solve this? – Andrea Moro Dec 28 '13 at 21:07
  • There is no easy way. You can try this ``IFS=: read -r _ _ _ _ _ home _ <<< "$(getent passwd "$SUDO_USER")"; echo "$home"`` to place user's home to ``$home`` variable. – Aleks-Daniel Jakimenko-A. Dec 28 '13 at 23:04
1

The problem is that your script sets PATH to a single directory, and that single directory does not contain a program called mkdir.

  • Do not use PATH as the name of a variable (use it to list the directories to be searched for commands).
  • Do learn the list of standard environment variable names and those specific to the shell you use (e.g. bash shell variables). Or use a simple heuristic: reserved names are in upper-case, so use lower-case names for variables local to a script. (Most environment variables are in upper-case — standard or not standard.)

And you can simply ensure that the directory exists by using:

mkdir -p ~/Dropbox/Web_Development

If it already exists, no harm is done. If it does not exist, it is created, and any other directories needed on the path to the directory (eg ~/Dropbox) is also created if that is missing.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278