Thank you for your help. Please have a look at my “do shell script” commands at the end.
-- list all files in a container including subfolders:
set source_folder to choose folder with prompt "Select the volume or folder to catalog."
set posix_path to (POSIX path of source_folder)
-- strip off slash at end:
if (posix_path as text) ends with "/" then
set posix_path to (characters 1 thru -2 of posix_path) as text
end if
-- handle apostrophes:
if (posix_path as text) contains "'" then
set posix_path to text returned of (display dialog "Please escape the apostrophes." default answer (posix_path as text))
end if
(*
-P If argument is a symbolic link, list the link itself rather than
the object the link references. This option cancels the -H and
-L options.
-R Recursively list subdirectories encountered.
-1 (The numeric digit ``one''.) Force output to be one entry per
line. This is the default when output is not to a terminal.
*)
set this_command to ("ls -P -R -1 " & posix_path) as text
-- if I put this_command on the clipboard and then paste into a terminal window and hit return, it works
do shell script (this_command) -- does not work
do shell script ("ls -P -R -1 " & posix_path) -- does not work
-- Once working, I want to capture the text that results:
set directory_text to do shell script (something_that_works)
set the clipboard to directory_text
display dialog "directory_text is ready to paste. Processing is finished."
Model: 2008 iMac OSX 10.9.5
AppleScript: 2.3.1
Browser: Firefox 36.0
Operating System: Mac OS X (10.8)
this works on my machine. quoted form of handles apostrophes and space characters in paths automatically.
Stripping of the trailing slash is not needed
-- list all files in a container including subfolders:
set source_folder to quoted form of POSIX path of (choose folder with prompt "Select the volume or folder to catalog.")
set this_command to "ls -P -R -1 " & source_folder
set the clipboard to (do shell script this_command)
display dialog "directory_text is ready to paste. Processing is finished."
This is my first adventure with “do shell script.” I was expecting to see the results in the terminal widow, which I did not. It seems that my script was working but I didn’t capture the output. But your version is much more tidy.
OK, but this is “syntactic sugar”, it doesn’t break the functionality.
As the POSIX path representation of a folder alias specifier always has a trailing slash, you can write
set source_folder to quoted form of text 1 thru -2 of POSIX path of (choose folder with prompt "Select the volume or folder to catalog.")
For the record this is what the POSIX standard has to say about this:
So to be clear, there are opportunities for exceptions. As a developer you should avoid double slashes when possible. I always disliked the trailing path separator from the path to and choose foldercommand. trim the last character as StefanK showed in his example.
The exceptions mentioned here, really pertains to the start of the path, ending a path with a slash, actually makes it easier for the shell or the system calls below it, if not deeper down, because a slash at the end, states that it is a directory, so, the shell doesn’t have to figure it out. but each to his own, I understand that someone dislikes to have to chop off one slash, or the other for aestethic purposes. But that chopping is certainly something that may come with a cost, not only by the chopping operation itself, but also by the fact that the Os/shell, will have to re-verify that it is a directory. Whigen the extra slash pops up in the middle of a path then it is also unnecessary to chop of the slash for making the path work, as two or more consecutive slashes are just taken for one slash anyway.
As for two starting slashes, I’d only worry about this, if I passed something to ftp, or some other command that uses something different the regular filepaths, like the http protocol and their likes, that is software like the browser, putty, wget, curl, ftp etc, that operates outside the normal file system.
The above is only true, as long as you’ll use the posix path for something that takes a posix path as an argument.
A HFS path isn’t tolerant to more than one ‘:’ in places, this is well worth to remember, and to check for, when converting posix paths to hfs paths, for use with AppleScript.
Path with a trailing slash like “/Users/” should be handled as “/Users/.” which is equal to “/Users”. So at the end there is no distinction between “/Users” and “/Users/” apart from extra handling needed when using the trailing slash. However practice have shown when commands tries to resolve paths by them self, instead of using the system, they can work differently (like GNU’s rm command).
To use the last character of a pathname to make a distinction between a directory or not is just bad practice and waiting for problems to happen. When normally a file is opened by asking the system for a file descriptor the distinction is made while resolving the path, it’s a flag in the inode structure to be exactly which tells you what type of file it is. If it’s not the desired type, an error will return.
The shell needs to figure out the file type of each file in the pathname ot properly perform the pathname expansion. It doesn’t rely on a last character either. It will read the inode’s file type to determine if the path can be expanded or not.
I still see a benefit in keeping the slash, when it is indeed a directory (folder), I agree to that the file will eventually be ‘statted’ before some operation is going down, but when the slash is there, then the utility in question may have ‘semantic knowledge’ of what is going to be performed, like rm would then know, that the user tried to delete a directory, which it won’t do unless you use the -f argument.
I disagree for the same reasons as above, but if the command in question, is return filepaths, and the command leaves the extra slash, like some commands do, at least mdfind I believe, then there is a valid reason for removing it, if you are to convert those paths returned into HFS paths, which will not ignore any extra colons. (Yes, I tested it. :))
As I wrote above, I agree with you there, but the last slash may help it make assumptions of what is going down.
Example:
If you leave out the last slash in the second argument, then all of the bak files could be written into single bak file, if the ./bak directory didn’t exist. In which case the original would have failed with an error message, since the directory ./bak/ didn’t exist.
Are you perhaps not understanding the difference between the Terminal application and a do shell scriptcommand in AppleScript?
If you want output to appear in the Terminal you have to talk to the Terminal application. The Terminal app will talk to various command shells and display results from shell commands, but it is separate and apart from them [the shells].
A do shell script command in AppleScript also talks to shells, but it returns the result back to AppleScript.
An example:
set _dir to POSIX path of (path to downloads folder)
tell application "Terminal"
activate
tell front window
if busy = false then
# It's a good practice to write your command to a variable - for easier debugging.
set shCMD to "'ls' -lp " & _dir
do script shCMD in selected tab
end if
end tell
end tell
mv does a system call named “rename” and either the source and target must be both non-directory or directory. So what you’re saying is by default not possible.
That is true, I even tried it with cp, but cp is also smart enough to test what it is, before it does anything.
But still, you don’t do any harm, by keeping the ending slash on a posix path that is a directory when passing it into a do shell script, on the ‘shell side’ of things. Probably most if not all included system utitlites will behave sanely like this.
But I’d rather have the slash there, than not, especially if a folder for instance is written in a script, because then it is easier to see what is going on.
And it doesn’t change my opinon of not using time (mine and the machines) on removing the last slash of a posix path at all. I can see no reason for this leading into some kind of trouble down the road, as long as the shell ignores any extra slashes.
What will eventually will lead one into trouble, is when the intent is to convert a returned filelist back from the shell into to HFS paths.
Then it should be preprocessed with something like below, before converting them to HFSPaths:
on removeSuperFluousSlashesFromPaths(txtWithPathList)
set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "//"}
set tmpText to text items of txtWithPathList
set AppleScript's text item delimiters to "/"
set txtWithPathList to tmpText as text
set AppleScript's text item delimiters to tids
return txtWithPathList
end removeSuperFluousSlashesFromPaths
Edit
It turns out that mdfind, which I really suspected to add an extra slash when given a directory ending in a slash, when used as an argument for the -onlyin option of mdfind, didn’t add any extra slash in the paths that were returned, but, some commands do just that.
I actually have turned on an autocomplete option in bash, so that I can see a trailing slash after directories, which is a great help.
The utilities strips off the slash, when they ‘stat’ a file but some utilities doesn’t strip the slash off the output of the command, which leaves us with the cases that /you/may/see//paths/like/these, getting rid of the extra slash, is the only reason I see for stripping a posix path from it, but if the paths are to be returned to an applescript for further processing, then stripping the slash up front is ok in my book, as that is the least expensive operation, since I otherwise would have to strip off the slashes afterwards.
set x to "/you/may//see//paths/like/these"
POSIX file x as text
--> "Macintosh HD:you:may:see:paths:like:these"
Although strangely:
set x to "/you/may///see/////paths/like/these"
POSIX file x as text
--> "Macintosh HD:you:may::see:::paths:like:these"
But I’m not sure that, in practice, anything other than one or two slashes is likely to arise. I’ve seen several cases in Cocoa where methods return paths containing doubled slashes.
I see them in the terminal window most of the time, the reason you see them by Cocoa methods may be that the methods does some system calls benath the surface.
We should file bug reports when we see them, if the result is likely to be handed back to AppleScript, -for robustness!
I just tried to add a colon to a HFS path, and tried to coerce that to an alias, and that didn’t work very well. I did it to simulate how a textual conversion from a posix path containing double slashes, to a HFS path using text item delimiters would work out.
Interesting to see that there are conversions that actually work (for the probable cases).
Not much point – they’re perfectly legal, and Unix isn’t going to be rewritten for AppleScript’s sake. I don’t think there will ever be more than two consecutive slashes returned, and POSIX file handles that fine.
By the way, the posix standard probably allows for the multiple slashes, so that you can have things working during prototyping/evolving. The most probable cause of getting an extra slash, is when passing a directory through a “system call” (by a system function in the execve family, that you can pass a unix command to, and get the stdin piped back into your program), if the next utility in the chain that one passed the directory to, also passes the directory with the slash, to another unix utility by a “system function”, and so on, then you may end up with multiple slashes in the final output, that are passed back, up through the levels of the “system functions”.
More interestingly, Apple still states in the Technical Note concerning the do shell script, that it is single threaded, but if you close the stdout, and stderr, and executes your unix command in the background, then the calling shell will return immediately, and your command, will execute on its own thread.
do shell script "/usr/bin/open -b \"com.apple.finder\" >/dev/null 2>&1 &"
Thougth I’d mention it while I mentioned the execve family of calls, because that is why it works. The calling shell, doesn’t wait for a process executed in the background, if it experiences that both the standard output and standard error is closed, unless it is called from a login shell with job control probably, (directly from a Terminal session).