do shell script: echo double backslash

Hello everyone,

this is my first post. First of all: thanks to everyone posting here. Macscripter has been a very helpful resource for me in the past.

Here is my problem:

I’m trying to match Windows UNC paths (\networkShare\folder) with perl’s regex. Usually I do something like the following:

do shell script "echo " & quoted form of "something" & "| perl -pe 's/some/any/g'" --> anything

which has always been working well for me.

When trying to ‘echo’ two backslashes, I found the following behavior that seems rather strange to me:

do shell script "echo " & quoted form of "\\\\" --> "\\" (AS escaped)

‘echo’ seems to automatically replace double backslashes with a single one, no matter where the double backslash is located. Therefore it also does the following:

do shell script "echo " & quoted form of "bla\\\\bla" --> "bla\\bla" (AS escaped)

And finally when echoing a UNC path:

do shell script "echo " & quoted form of "\\\\networkShare\\folder"

it returns two lines in the result window with a single leading backslash:

What am I not getting here? Usually the ‘quoted form’ works very well in such cases.

Any help welcome. Thanks a lot!

Luke

AppleScript: 2.1.2
Browser: Safari 533.18.5
Operating System: Mac OS X (10.6)

That is an applescript effect, not an echo effect. For example, try to create a string like this in applescript… I said “Hello”.

Since the quote mark is special to applescript (because that’s what we use to encapsulate a string), in order to use it in a string you must “escape” the quote mark.The following is what you would have to type to include a quote mark in a string…

set theString to "I said \"Hello\""
display dialog theString

As you can see the escape character \ is another special applescript character. Therefore to include a backslash character in a string in applescript you must also escape it…

set theString to "Here is a backslash character in an applescript string \\"
display dialog theString

So basically you need to escape special applescript characters in strings, such that applescript will pass the proper string to wherever you want to use the string… in your case with the echo shell command. The “quoted form of” use with a shell command is an applescript command that properly escapes strings for use with the shell. The shell has different rules for escaping characters and luckily applescript has the “quoted form of” command to properly handle the shell rules for you. So one command is for use in applescript and one command is for use with the shell.

Hello Hank,

thanks for your answer.

I am aware of the fact that some chars have to be escaped in AppleScript. That’s why my two backslashes are properly AS escaped using four backslashes in total and then passed to the shell using ‘quoted form of’.
Info: I also used the escaped form for the results that I posted (–>).

My problem is that the ‘do shell script “echo…”’ literally replaces any occurrence of \ with .

Please try it out using my example number 2 and you will see what I mean.

It seems to me that this only happens to double backslashes. Things like

do shell script "echo " & quoted form of "\"\"" --> "\"\""

return the expected results.

Does anyone know anything about this?
Is it a bug or some special shell voodoo that I am not aware of?

Thanks
Luke

I’m not seeing what you describe. Try this… applescript and the echo command both properly return \.

set a to "\\\\"
display dialog a
do shell script "echo " & quoted form of a

Please try this and you will see what I mean:

set a to "\\\\"
display dialog a --> two backslashes
set a to do shell script "echo " & quoted form of a
display dialog a --> only one backslash left

Please do not forget that strings in the results window remain AppleScript escaped. It may look like two, but it is just one backslash.

Thanks for your help.

That’s an interesting example. Now I see what you mean. Try this though. It seems that the proper command is sent to the shell, although when the result of the shell command is passed back to applescript is where your problem arises. And I’m not sure what to do about that.

set a to "\\\\"
display dialog a
tell application "Terminal"
	do script "echo " & quoted form of a
end tell

Good point. Thank you.

I was about to think that writing the output to a file and then read it back in would work around this problem. But then I tried this:

do shell script "echo " & quoted form of "\\\\" & " > ~/Desktop/test.txt"

Only one backslash in ‘test.txt’ :wink:

Very strange (aaaaaaahhhh…)

Very strange indeed as this works…

set a to "\\\\"
tell application "Terminal"
	do script "echo " & quoted form of a & " > ~/Desktop/test.txt"
end tell
set b to read file ((path to desktop as text) & "test.txt")

So the “do script” in a terminal window is different than a “do shell script” command… never knew that.

Just a thought… a terminal window uses the bash shell whereas the “do shell script” command uses the sh shell… so is that the reason for the difference?

Yep, that’s the difference. It’s how sh is handling it versus bash. If you type this in the Terminal the output file will contain only 1 backslash…

hmcshane@macbook:~ $ sh
hmcshane@macbook:~ $ echo '\\' > ~/Desktop/test2.txt

You see the first “sh” command puts us in the sh shell and it sees the double backslash as one slash… whereas bash doesn’t. So we need a way to make “do shell script” use the bash shell. I’m not sure how to do that but I’ll think about it.

Neither did I. You live and learn :wink:

Yes, making ‘do shell script’ use the bash shell is exactly what I was thinking after reading your last post (#9) as well. To bad that I don’t know how to do so yet :wink:

I tried to do it like in terminal

do shell script "bash; echo " & quoted form of "\\\\"

but that didn’t do it (I guess that would have been too easy).

I guess I could write the UNC path to a file using Standard Addtions, process that file in the shell and then read the result back in. But I’d rather do it the ‘normal’ way using ‘do shell script’ and ‘echo …|…’.

Thanks for your support.

Does anyone know by heart how to change the shell that ‘do shell script’ uses or an alternative solution?

See here for that. Look under the section titled “Q: How do I run my command with a shell other than sh?”

I can’t get it to work properly with bash. However tsch works.

set a to "\\\\"
do shell script "/bin/tcsh -c 'echo \"" & a & "\"'"

Notice that I did not use “quoted form of”. Putting the echo command in single quotes (e.g. quoted form of) doesn’t work… even on the command line… double-quotes does work. All of this is really strange!

Hank, thanks for the link and the section. I scrubbed through this page earlier but obviously missed that section.

I tried something similar:

do shell script "/bin/bash -c \"echo " & quoted form of "\\\\" & "\"" --> "\\" (AS escaped)

but that doesn’t do it either.

I like your tcsh command but unfortunately I wanna pipe an entire email content from Apple Mail into perl and really need to use the ‘quoted form’ to be sure that everything is properly escaped.

I understand. The best solution I think would be to create a bash shell script on-the-fly. Then run it and get the result, then delete the shell script. It’s a little messy but it works!

set a to "\\\\"
set cmd to "echo " & quoted form of a

-- create a bash shell script
set LF to character id 10 -- a unix line feed
set bashScriptPath to (path to desktop as text) & "bashScript"
set bashText to "#!/bin/bash" & LF & cmd

-- write the bash script
set openFile to open for access file bashScriptPath with write permission
write bashText to openFile as text
close access openFile

-- make the bash script executable
do shell script "chmod a+x " & quoted form of POSIX path of bashScriptPath

-- run the bash script
set theResult to do shell script quoted form of POSIX path of bashScriptPath

-- delete the bash script
do shell script "rm " & quoted form of POSIX path of bashScriptPath

return theResult

Here we go. Thanks, Hank! With your help I think I came up with a solution that works.

First I tried this, which works:

set a to "\\\\netWorkShare\\folder\\file"
set a to quoted form of a
set b to quoted form of ("echo " & a)
do shell script "/bin/tcsh -c " & b --> "\\\\netWorkShare\\folder\\file" (AS escaped)

But when I tried to pass the following

it failed (Unmatched single quote).
NOT WORKING:

set a to "test line \"1\"\ntest line \"2\"\n\n\\\\netWorkShare\\folder\\file\n\ntest line \"3\"\ntest line \"4\""
set a to quoted form of a
set b to quoted form of ("echo " & a)
do shell script "/bin/tcsh -c " & b --> ERROR: Unmatched '.

So I tried this with /bin/bash:

set a to "test line \"1\"\ntest line \"2\"\n\n\\\\netWorkShare\\folder\\file\n\ntest line \"3\"\ntest line \"4\""
set a to quoted form of a
set b to quoted form of ("echo " & a)
do shell script "/bin/bash -c " & b --> returns correct string, double backslashes still intact

and it returns the expected result.

Also piping it into perl seems to work well:

set a to "test line \"1\"\ntest line \"2\"\n\n\\\\netWorkShare\\folder\\file\n\ntest line \"3\"\ntest line \"4\""
set a to quoted form of a
set b to quoted form of ("echo " & a)
do shell script "/bin/bash -c " & b & " | perl -pe 's/\\\\/a/g'" --> all backslashes replaced by 'a'

Thanks again, Hank, for your time and your interest.

Hoever, I still agree that this is very strange. If anyone has an explanation, I’ll be very grateful.

Ups, we posted at the same time.

I will definitely use your solution if I still run into more (strange, inexplicable) problems. I cannot understand what is happening here.

Really, Hank, thanks for your support. This was a real pain which is now eased.

I’m happy to help and glad you got something working. This was at least interesting although very frustrating too. Anyway good luck.c:D

Well you’re simply using the wrong echo here. I always use the POSIX echo because it doesn’t have this problem. You’re using another echo by default but when you’re using echo in the /bin folder you’ll see both times two slashes.

set a to "\\\\"
display dialog a --> two backslashes
set a to do shell script "/bin/echo " & quoted form of a
display dialog a --> two backslashes

Also I found it because the default echo also doesn’t support the ignoring trailing new line when piping to another command. So in my opinion use also ‘/bin/echo’ instead because the default echo will always send a trailing newline when piping.

Sorry, haven’t checked in in a while.

Thanks for your tip, DJ Bazzie! It’s very helpful! Great finding!