PDA

View Full Version : Applescript - escape characters question




Lanky Streak
Jun 4, 2009, 02:21 PM
I have a one-line command that works fine from the command prompt in Terminal:

echo -e "C\x03" > /dev/cu.usbserial-000012FD

This command controls a USB relay card so sending the hex value 03 sets relays #1 and #2 ON (e.g. binary 00000011 = hex 03).

I want to know how to implement this command as an Applescript. I've tried this:

do shell script "echo -e \"C\\x03\" > /dev/cu.usbserial-000012FD"

and every permutation I can think of for escaping the double-quotes and backslash characters but I always get an error from the script editor. My apologies if this is a really simple problem, I'm a Mac newbie, but how can I get this script to run from Applescript?



lee1210
Jun 4, 2009, 02:28 PM
This may be cheating, but you could just put the escape sequence in a file, and then just cat that file to the device in your applescript instead of having to have the sequence literal in there.

-Lee

Lanky Streak
Jun 4, 2009, 02:51 PM
Thanks for the quick reply Lee. It is cheating and it kind of works, but not completely. If I put

C20

in my text file and then execute

do shell script "cat /users/chris/Library/scripts/Relay.txt > /dev/cu.usbserial-000012FD"

it switches the relay board, but throws the wrong relays because.....
the text file contains ASCII characters so it interprets that ASCII digit 2 as Hex 32, sends that to the relay board, which switches on relays #2, 5, and 6 (i.e. hex 32 = binary 00110010 = decimal 50 which is the ASCII for "2").

How can I send a single byte instead of ASCII characters from my file?

lee1210
Jun 4, 2009, 03:41 PM
If you're using vi, it would be:
i (to get into insert mode)
shift+c (to type a C)
ctrl+v (tell the shell you have a literal you want it to type)
ctrl+c (type an ^C, which should be ascii 3)
esc
:w myesc
:q<return>

Then you'll need to:
head -c2 myesc > myesc2

Because vi(m) will add a trailing newline.

-Lee

EDIT: You can check the bytes in your file with:
od -t d1 myesc2

Lanky Streak
Jun 4, 2009, 04:01 PM
Well it wasn't the answer I was expecting but I am really grateful to you Lee for producing a working solution. This works like a charm.

I particularly appreciate you taking the trouble to give me step-by-step vi commands. vi is an editor I used to use all the time as a rookie C programmer many years ago but I had long since forgotten it in this age of sophisticated software development tools with auto-indenting, color-coded editors. It's a neat solution and will serve my purposes nicely so thanks again.

However if anyone knows of a way to embed a byte within a script command in Applescript I'd still like to learn it.

Mars™
Jul 29, 2009, 07:05 PM
Well it wasn't the answer I was expecting but I am really grateful to you Lee for producing a working solution. This works like a charm.

I particularly appreciate you taking the trouble to give me step-by-step vi commands. vi is an editor I used to use all the time as a rookie C programmer many years ago but I had long since forgotten it in this age of sophisticated software development tools with auto-indenting, color-coded editors. It's a neat solution and will serve my purposes nicely so thanks again.

However if anyone knows of a way to embed a byte within a script command in Applescript I'd still like to learn it.

If you want to escape characters in applescript,, how about using javascript within applescript.. such as

set datax to run script "alert(escape('!@#$%^&*}{'))" in "JavaScript"

Lanky Streak
Jul 30, 2009, 02:32 AM
If you want to escape characters in applescript,, how about using javascript within applescript.. such as

set datax to run script "alert(escape('!@#$%^&*}{'))" in "JavaScript"

Thanks for that Mars. I understand how to do this with printable characters but how can I escape non-printable characters such as ASCII 0 to 32?

mysterytramp
Jul 30, 2009, 06:29 AM
What's the error from the script editor? Is there something wrong with the string, or is there an error returned from do shell script?

You might try this:

set escapeChar to ascii character (3)
set myString to "echo -e " & quote & "C" & escapeChar & quote & " > /dev/cu.usbserial-000012FD"


or this:

set testString to "echo -e " & quote & "C" & (ASCII character (92)) & "x03" & quote & " > /dev/cu.usbserial-000012FD"


but I wonder if the error isn't that Terminal can't parse what AppleScript is sending it.

mt

Lanky Streak
Jul 30, 2009, 03:18 PM
Perhaps I didn't explain my question very well. I don't want to run this command in Terminal, I just did that to prove the concept. I actually want to run this as a script, for example in the Leopard Script Editor.

Your example is a huge step forward mt but what do I do with the string I've created? If I paste your second example into Script Editor, do I then follow it with

do shell script testString

? If so, it doesn't work. The script appears not to pass the correct string to the device.

mysterytramp
Jul 30, 2009, 06:00 PM
yes, you'll want to add:

do shell script testString


You might also try single quotes instead of double quotes.

set testString to "echo -e 'C" & (ASCII character (92)) & "x03' > /dev/cu.usbserial-000012FD"

The error I get is a permission error. Is that what you get?

mt

Lanky Streak
Aug 2, 2009, 01:19 AM
At the risk of repeating myself, all I want to do is to send two bytes to the device using Applescript. For example ASCII 67 (the character 'C') and ASCII 3 (the non-printing ETX character). I feel it should be so simple, yet it isn't.

MysteryTramp has made some really valuable suggestions but none of them works correctly.

set testString to "echo -e 'C" & (ASCII character (92)) & "x03' > /dev/cu.usbserial-000012FD"
do shell script testString

This doesn't return an error but it doesn't send the correct two bytes to the device either. If I execute that script the Event Log shows:

tell current application
ASCII character 92
"\\"
do shell script "echo -e 'C\\x03' > /dev/cu.usbserial-000012FD"
""
end tell

If I run MT's first suggestion...

set escapeChar to ASCII character (3)
set myString to "echo -e " & quote & "C" & escapeChar & quote & " > /dev/cu.usbserial-000012FD"
do shell script myString

...again no error is returned but the device does not respond correctly. The Event Log shows:

tell current application
ASCII character 3
""
do shell script "echo -e \"C\" > /dev/cu.usbserial-000012FD"
""
end tell


MT's next suggestion was...

set testString to "echo -e " & quote & "C" & (ASCII character (92)) & "x03" & quote & " > /dev/cu.usbserial-000012FD"
do shell script testString

Once again no error is returned but the device doesn't respond correctly and the Event Log shows:

tell current application
ASCII character 92
"\\"
do shell script "echo -e \"C\\x03\" > /dev/cu.usbserial-000012FD"
""
end tell

I have repeatedly checked that the device is working by sending commands directly from Terminal and it always responds correctly so for some reason this Applescript isn't sending the correct two bytes to the device. Once again here's the line that works correctly in Terminal:

echo -e "C\x03" > /dev/cu.usbserial-000012FD

I just need to replicate this in Applescript. Any other suggestions guys?

ncl
Aug 2, 2009, 05:29 AM
My knowledge of AppleScript is limited but I tried the first suggestion in your post, by replacing the output to /dev with a pipe to hexdump:

set testString to "echo -e 'C" & (ASCII character (92)) & "x03' | hexdump -C"
do shell script testString

And here is the result:

00000000 2d 65 20 43 03 0a |-e C..|

So, apparently, the "-e" is sent as part of the ouput of echo. By simply removing it:

set testString to "echo 'C" & (ASCII character (92)) & "x03' | hexdump -C"
do shell script testString

I get:

00000000 43 03 0a |C..|

Which looks like what you want.

Lanky Streak
Aug 2, 2009, 06:40 AM
Yes! That's it! Thank you ncl, you are a real star. This solution works and provides exactly what I was seeking. It has taken a while but in this forum I have learnt so much and met several talented folk who have generously shared their time to help others. I hope one day I will have the knowledge to reciprocate.

For the benefit of anyone else who comes along here having encountered the same problem, here is the working solution:

set testString to "echo 'C" & (ASCII character (92)) & "x03' > /dev/cu.usbserial-000012FD"
do shell script testString
:)