Update: Solution below
Say you have a list of selected items from Finder. Say there are some files, folders, various bundles, and even some applications included in the selection.
Now say you only want those items that are (in UNIX terms) directories. I.e. you only want items you can cd
to in the terminal.
You can check each item's kind
property and see if it equals "Folder", but that doesn't work for application bundles or other bundles/packages, though they are in fact "folders" (directories)
If the items are actual file objects (not aliases), you can check each item's class
property... except that doesn't always work either, since bundles a开发者_开发技巧re now "document file" instances, and applications are "application file" instances.
It's worse if you only have a list of aliases rather than actual file objects, since you can't check the class
property; it'll always just say "alias".
The only solutions I can think of, are to either get the POSIX path of each item, and see if it has a trailing forward slash, or to send its path to a script written in a different language, which can check if something's a directory or not.
Both ideas seem crazy to me. Checking for a trailing forward slash is extremely hacky and fragile, and feeding everything to a different script is complete overkill.
Update: What Asmus suggests below does seem to be the only a good solution, as it seems there's no way for AppleScript to figure it out on its own:
do shell script "file -b " & filePosixPath
That'll return the string "directory" for folder, bundles, applications, packages, etc. etc.
But note(!) that for disks, it returns "sticky directory".Here's a generalized function that works pretty well
on isDirectory(someItem) -- someItem is a file reference
set filePosixPath to quoted form of (POSIX path of (someItem as alias))
set fileType to (do shell script "file -b " & filePosixPath)
if fileType ends with "directory" then return true
return false
end isDirectory
There is a simple applescript solution. You can check if something is a "package" using system events.
tell application "Finder" to set theItems to (selection) as alias list
set canCDItems to {}
tell application "System Events"
repeat with anItem in theItems
if anItem is package folder or kind of anItem is "Folder" or kind of anItem is "Volume" then
set end of canCDItems to contents of anItem
end if
end repeat
end tell
return canCDItems
If the variable is just a string, use this form:
on isDirectory(someItem) -- someItem is a string
set filePosixPath to quoted form of (POSIX path of someItem)
set fileType to (do shell script "file -b " & filePosixPath)
if fileType ends with "directory" then return true
return false
end isDirectory
Im using an alfred workflow which run this script with a keyboard combination of keys (⎇+F2). The script opens a terminal application based on what I got selected on finder, if is a folder then open a terminal inside selected folder, if is a file then open a terminal on parent folder. worked flawless
set pathList to "~"
if frontmost of application "Finder" then
tell application "Finder"
set fileList to selection as alias list
if fileList is not equal to {} then
set someItem to (item 1 of fileList) as text
set filePosixPath to quoted form of (POSIX path of someItem)
set fileType to (do shell script "file -b " & filePosixPath)
if fileType ends with "directory" then
set pathList to filePosixPath
else
set pathList to (quoted form of POSIX path of (folder of the front window as alias))
end if
else
set pathList to (quoted form of POSIX path of (folder of the front window as alias))
end if
end tell
end if
tell application "System Events"
tell application "Terminal"
activate
if exists window 1 then
do script ("cd " & pathList) in window 1
else
do script ("cd " & pathList)
end if
end tell
end tell
I needed this today, as I was trying to plug a couple of diff tools into Finder for Mountain Lion and wanted to check if the selected item or items were folders or files. This worked for me:
tell application "Finder"
set sel1 to the selection
set class1 to class of (item 1 of sel1)
set cs to (class1 as string)
...
if cs = "folder" or cs contains "class cfol" then
set choice to display alert "Which tool?" buttons {"opendiff", "diffmerge"}
set tool to (button returned of choice)
I found I needed to test cs for both cases, depending on whether I was running in the AppleScript Editor or as a result of clicking a toolbar button on Finder. Far from the neatest but, shorter than the previous AppleScript-only solution, this would be my alternative proposal
on isDirectory(someItem)
((class of someItem) as string) contains "fol"
end isDirectory
Results of full testing in all circumstances welcome!
Standard Additions offers this (no System Events necessary):
set isBundleType to package folder of (info for (choose file))
精彩评论