The structure of this code was influenced by some code Apple posted under “Changing Case” here. Escaping is much better than quoting, especially if you want to build on a POSIX path by adding things to it. I have a similar handler in the latest script I’ve uploaded.
on escapepath(filepath)
set evildoers to "*?[]^{}~$!^&|<>;()`\\'\" "
set escaped to {}
set filepath to filepath as text
set filepath to POSIX path of filepath
set AppleScript's text item delimiters to "/"
set filepath to text items of filepath as list
set AppleScript's text item delimiters to ""
repeat with seg in filepath
repeat with char in seg
set evil to offset of char in evildoers
if evil ≠0 then
set escaped to escaped & "\\" & char
else
set escaped to escaped & char
end if
end repeat
set escaped to escaped & "/"
end repeat
set escaped to escaped as text
set escaped to items 1 through -2 of escaped as text
return escaped
end escapepath
set flurryPath to "/System/Library" & quoted form of "/Screen Savers" & "/Flurry.saver"
--> "/System/Library'/Screen Savers'/Flurry.saver"
do shell script "cd " & flurryPath & "; pwd"
I thought that at first Qwerty, but I can imagine someone wanting to do this. However, it’s really just a specialized find/replace script (as compared to these threads: str_replace(), Find & Replace).
Side note: We have a topic on changing text case: Change Text Case
Edit: I don’t understand why you’re breaking up the path when you escape the characters. Looping over each character in the path will probably have a performance impact (if you measure such things). I’m not used to using offset, so here’s a delimiter-based version:
-- somePath must be some sort of text
on escapePOSIX(somePath)
set ASTID to AppleScript's text item delimiters
set escapeNeeded to {"\\", space, ASCII character 34, tab, "(", ")", "[", "]", "{", "}", "<", ">", "|", "!", "?", "$", "~", "^", "*", "`", "'", ";", ASCII character 27}
try
repeat with thisChar in escapeNeeded
set AppleScript's text item delimiters to {thisChar}
set somePath to text items of somePath
set AppleScript's text item delimiters to {"\\" & thisChar}
set somePath to "" & somePath
end repeat
end try
set AppleScript's text item delimiters to ASTID
return somePath
end escapePOSIX
escapePOSIX("/System/Library/Screen Savers/Flurry.saver")
--> "/System/Library/Screen\\ Savers/Flurry.saver"
Very nice idea, Alex, and nice implementation too, Bruce. Something very similar could help with shell scripts like the one below and its escaped version below:
-- A valid shell script should be on the clipboard
set shellScript to the clipboard
set ASTID to AppleScript's text item delimiters
set escapeNeeded to {"\\", "\""}
try
repeat with thisChar in escapeNeeded
set AppleScript's text item delimiters to {thisChar}
set shellScript to text items of shellScript
set AppleScript's text item delimiters to {"\\" & thisChar}
set shellScript to "" & shellScript
end repeat
end try
set AppleScript's text item delimiters to ASTID
set the clipboard to "do shell script \"" & shellScript & "\""
beep
I am using the escapePOSIX() handler in an AS Studio application that launches a command line app that is kept within the Contents/Resources/ folder of the application. I just wanted to say that this handler works terrifically!
I did come across one problem and I was wondering if anyone knows of a solution.
A Japanese user is getting less than optimal results with my app as it is unable to find the command line utility. I believe this is due to a mistranslation of the POSIX path when Japanese characters are present.
Here is the context of my use of the escapePOSIX() handler:
set POSPath to POSIX path of (path to me)
set rPath to POSIX path of POSPath & "Contents/Resources/kaid/"
set kaidPath to escapePOSIX(rPath)
set setLogFile to ((path to temporary items) as Unicode text) & "kaidEngineLog.txt"
set theLogFile to POSIX path of setLogFile
set kaidPass to content of text field "startKaidWith" of window "prefs"
do shell script "cd " & kaidPath & "; ./kaid -c kaid.conf &> " & theLogFile & " &" password kaidPass with administrator privileges
do shell script "sudo -k"
The error he is getting is:
/bin/sh: line 1: ./kaid: No such file or directory
I got this same error, I believe due to a space in the name of the app (Kaid Commander) which was remedied by this wonderful escapePOSIX() handler, and I believe that there may be something related to the Japanese characters that is causing some sort of escape problem.
Does anyone have any ideas on a possible solution?
Perhaps I am going about this all wrong to begin with and there is a better way to launch this item?
set kaidPass to content of text field "startKaidWith" of window "prefs"
set kiadExec to quoted form of POSIX path of ((path to me as Unicode text) & "Contents:Resources:kaid:kaid")
set logPath to quoted form of POSIX path of ((path to temporary items as Unicode text) & "kaidEngineLog.txt")
do shell script kaidExec & " -c kaid.conf &> " & logPath & " &" password kaidPass with administrator privileges
Hi Adam, while looking at this thread, I thought that a script idea from there could also help with the above script. and save escaping for applescript.
example
on ACom_run(script_text, Code)
set the_name to name of document 1
set the_contents to contents of document the_name
set AppleScript's text item delimiters to ("Start_Point_" & Code as string)
set the_content to text item -1 of the_contents -- this works from bottom of text to first break point "Script_Start_Point"
set AppleScript's text item delimiters to ("End_Point_" & Code as string)
set script_text to text item 1 of the_content
set AppleScript's text item delimiters to ""
return script_text
end ACom_run
set script_text to ""
set Code to "Shell1"
set shell_text to ACom_run(script_text, Code)
do shell script shell_text
-- Adams shell script
-- Start_Point_Shell1 echo $PATH | sed -e 's/:/ /g' | xargs -J % find % -maxdepth 1 \( -type f -or -type l \) | xargs basename | sort | uniq | xargs whatis 2> /dev/null | grep -E '\((1|1m|6|8)\)' | perl -ne '($name, $descrip) = m/^(.*?)\s+- (.*)$/; $name =~ s/\((1|1m|6|8)\)//g; printf("%-20s - %s\n", $name, $descrip)' > ~/desktop/Unix_Functions.txt End_point_Shell1
set Code to "Shell2"
set shell_text to ACom_run(script_text, Code)
set ass to do shell script shell_text
-- A Cameron Hayne shell script to find urls in a file
-- Start_Point_Shell2 perl -ne 'if (/src="([^"]*)"/) { print "$1\n"; }' path/to/Foo > ~/desktop/Unix_Functions2.txt End_point_Shell2
Its the open document. (The script itself)
Which does limit the using of commenting this way to scripts run from Script editor some what. :rolleyes:
(Unless I can find a way to read the script file and coerce it into text.)