Script to check folder and create if doesn't exist

DJ did explain it, but it can be confusing at first. :slight_smile:

With logical OR, only one of the subconditions needs to be true for the entire proposition to be true. Most computer languages (possibly all) test OR’d conditions in the order they’re presented until one of them turns out to be true or the last test returns its result. If a true result comes up, there’s no need to test any of the following conditions, so true is returned for the entire OR’d group at that point. Only if a condition proves false is the next test (if any) carried out.

The bash trick here is a sleight-of-logic based on this. If the folder exists, the test for it returns true and the script doesn’t bother executing the statement after the OR (||). If the folder doesn’t exist, the false result causes the script to try again with what it believes is another test, but which is in fact the creation of the folder. This also returns a true or false result in bash, so the script doesn’t get confused.

Conversely, with logical AND (&&), conditions are tested in the order presented until one of them turns out to be false.

OK, thanks. I get that.

I still have my question: Why not use a logical NOT rather than a logical OR?

I don’t know the bash syntax, but in pseudo code:

The logic is immediately obvious to almost all readers.

More obvious than:

I’ll have to leave that for DJ to answer. :slight_smile:

But why bother checking if the folder exists (or doesn’t) at all? As I said somewhere above, if you use mkdir’s -p option, it’ll create the folder if it doesn’t exist and not error if it does.

Sounds good to me! Why didn’t you just say that instead of explaining the OR logic? LOL
Sorry, I missed your earlier post about the -p option.

From the mkdir manual:

So, all we need is:


do shell script "mkdir -m 755 -p " & subFolder

Correct?

Because logic’s so interesting! :slight_smile:

Yes. Or:

do shell script "mkdir -p -m 755 " & subFolder

Or:

do shell script "mkdir -pm 755 " & subFolder

There is actually one difference between this and checking for the folder’s existence first which could be important. Using the -p and -m options together imposes the specified permissions even where the folder already exists with different permissions. You may not always want this.

I wouldn’t say more obvious, I would say it’s more common. It’s personal preference because the if-statement cannot be written down like you wrote it down. In bash an if-statement would look like

[format]if [[ ! -d theFolder ]]
then
mkdir.
fi
[/format]
if you want to write it down as compressed as possible it would look like:
[format]if [[ ! -d theFolder ]];then
mkdir.;fi[/format]

So I think that especially compared to the last compressed example that using OR is more “obvious” than using NOT.

Update: here another example to check if a file exists and return an to boolean coercible string.

set fileExists to (do shell script "if [[ -e " & quoted form of theFile & " ]]
then
echo yes
else
echo no
fi") as boolean

in a more compressed way:

set fileExists to (do shell script "if [[ -e " & quoted form of theFile & " ]]; then
echo yes; else
echo no; fi") as boolean

Or when using the AND and OR operator:

set fileExists to (do shell script "[[ -e " & quoted form of theFile & " ]] && echo yes || echo no") as boolean

To me the last one with the AND and OR operator is the easiest to read. But like I said, it’s more like a personal preference rather than one being better than the other.

Nigel, you seem to be feeding us one partial piece of critical information at time. :frowning:

If I had known when you first suggested using the -p switch with mkdir that it changes permissions on existing directory, then I would NOT have considered it at all.

Knowing that now eliminates using your suggestion.

I appreciate your help, but in the future if there are potentially adverse side effects to a suggestion you are making please tell us about it up front. This especially applies to lesser known scripts like shell scripts. Had I not pursued many follow-up questions about mkdir, I, and probably many other readers, would have not realized this issue.

Thanks.

I mean the error dialog (OS?) that pops up stating folder already exists.

Thanks for the detailed explanation, DJ.

The syntax above it the most clear to me.

IMO, using the (A OR B) syntax to execute B only IF A is false is a more advanced technique, and may not be easily recognized by a large number of scripters.

In this case you should check if the shared volume is already mounted to skip the mount line on success.

So, to recap:

The most clear syntax (IMO) for creating a new directory (folder) IF it does not already exist is:
EDIT: 2016-04-04 14:01 CT


### This revised script corrects errors in DJ's syntax, and provides complete script, which I have tested ###

set newFolderPath to quoted form of (expandPath("~/Documents/Test/NewFolder"))

set cmdStr to "if [[ ! -d " & newFolderPath & " ]]; then 
mkdir -m 755 " & newFolderPath & "; fi"
do shell script cmdStr

on expandPath(pPathStr)
	local fullPath
	set fullPath to pPathStr
	
	if fullPath = "~" then
		set fullPath to (POSIX path of (path to home folder))
	else if fullPath starts with "~/" then
		set fullPath to (POSIX path of (path to home folder)) & text 3 thru -1 of fullPath
	end if
	
	return fullPath
end expandPath

where
newFolderPath is the quoted form of the full POSIX path to the folder.
! is logical NOT
-d is a bash conditional expression that returns TRUE if the folder exists
-m 755 is the mkdir switch to set permissions on the folder to
read, write and execute by the owner, read and execute by group members, read and execute by others, and no set-uid or set-gid behaviour

OR you can use this syntax which makes use of the formulation:
(A OR B)
execute B only if A is false


do shell script "[[ -d " & folderPath & " ]] || mkdir -m 755 " & folderPath

@DJ:

This code contains numerous syntax errors, which I corrected in my above script.

I would avoid using the -p switch on mkdir because it will change the permissions on an existing directory (folder).

My sincere thanks to all of the great AppleScript gurus above who helped me learn this.
I hope others will find it useful as well.

Look out, JMichaelTX. There are potentially adverse side effects to everything about computer scripting and programming, whether suggested by me or anyone else. It’s up to you to evaluate and test any information you receive to make sure it’s suitable for your purposes. No-one here is expected to second-guess or take responsibility for their advice being used for any purpose other than the one for which it’s intended.

In this thread, the OP wrote:

And later:

The clear implication is that if the folder exists, it’s because it’s already been created for the same purpose and already has its permissions set for that purpose. My -p suggestion is 100% in accordance with that.

I can’t see anything in your posts above which suggests you might not want the permissions set if the folder already exists. You only ask for an explanation of the logic in the bash script.

I did point out as an afterthought, when it occurred to me, that the -m option is still operative even when the folder already exists ” it’s an easy thing to check for yourself ” but it was more for the benefit of later readers that from any inkling that your requirements were different from the OP’s.

That’s a nice CYA statement. :wink:
Given your reputation, sir, I expected more from you. Consider lesson learned.

I agree that each person has to take full responsibility for using any suggestions or code received from a post on an Internet forum, and to fully understand and test before using.

Having said that, my personal ethics are that if I know of a side effect or adverse result of using something that I am suggesting, then I feel compelled to advise the reader of that. If you choose to throw out suggestions for unsuspecting users without providing any warnings that your already know about, then that is up to you sir.

I surely don’t have to tell you that these threads are for the benefit of all users, not just the one who made the original post. I’m sure you know that other users in search of answers will come along later, and use what they find.

In the case of mkdir is hard to know even where to find documentation if you are not an experienced shell scripter.

Given that the discussion at the time was about testing for an existing folder, you suggested a method that does not just test for the folder, but also sets permissions if the folder does exist. So at the best, IMO, that was bad advice. I still feel that you should have advised us at the time of the suggestion that it also sets permissions.

Which I did on purpose :slight_smile: I though the ‘.’ character speaks for itself.

update:
comment on expanding path. Since bash is quite new for you by default the tilde is replaced by the home directory but it can contain a path to any folder. That’s because the tilde is an environment variable.

LOL, that’s not what I was referring to.

You need a space after the “;” and before the “]]”

Try testing it as you have it, with the “…” replaced, of course.

You don’t need a space behind a ‘;’, it’s an habit I do for better readability when I write shell scripts. The space behind theFolder is the only mistake I have corrected, I have not tested the code and wrote it quickly, my apologies.

I am obviously a rank amateur when it comes to shell scripting.
When I tried your example in Terminal, it failed.

I saw two examples using the bash “if” structure, and both of them had a space after the “;”, including yours:

I also read that in Terminal/Bash, the syntax is very sensitive to spaces.
All I know is that when I added the indicated spaces, the script worked.

Sometimes it’s better safe than sorry and, yes, bash is sensitive to spaces. Every operator and primary should be surrounded by spaces. To fit all different notations here to make it clear what and what you cannot do in bash.

set fileExists to (do shell script "if [[ -e " & quoted form of theFile & " ]];then echo yes;else echo no;fi") as boolean

But it makes readability worse and probably no Bash scripter, beginner or amateur, would choose that over AND and/or OR operators and definitely experienced ones not. When someone asks a one liner if statement the logical operators are used in Bash. Keep in mind that I do prefer the Bash scripts in do shell script written in a more Bash style than considering AppleScript style, so that only speaks for myself.

DJ, maybe you’ve been programming in Bash so long that the (A OR B) technique seems more natural to you, and that’s fine. But I don’t think you can assume that “no bash scripter, beginner or amateur, would choose that over AND and/or OR operators”, because I’m at least one who would.

When I’m reading a language I am not very familar with, use of the “IF/THEN” construct is very clear, and sends an immediate signal to me that this statement is an IF test.

When I see (A OR B), especially when it is used with other strange (to me) syntax like:
do shell script "[[ -d " & folderPath & " ]] || mkdir -m 755 " & folderPath

then I have to stop, and figure out what is really going on here. Add to that, that there are many different symbols for logical OR.

So, IMO, use of IF/THEN is must easier to read than (A OR B).

But we each have our own preferences, and experiences. :slight_smile:

Sure, and it’s also a preference of mine because one is not better than the other. To be clear, I’m not trying to convince you to use otherwise, just showing all the different forms on how to write an if-statement down in Bash. It’s yours to pick the notation you like most. :slight_smile: