Applescript - escape characters question

Discussion in 'Mac Programming' started by Lanky Streak, Jun 4, 2009.

  1. macrumors newbie

    Joined:
    Apr 28, 2009
    Location:
    Wiltshire, UK
    #1
    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?
     
  2. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #2
    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
     
  3. thread starter macrumors newbie

    Joined:
    Apr 28, 2009
    Location:
    Wiltshire, UK
    #3
    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?
     
  4. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #4
    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
     
  5. thread starter macrumors newbie

    Joined:
    Apr 28, 2009
    Location:
    Wiltshire, UK
    #5
    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.
     
  6. macrumors newbie

    Joined:
    Jul 29, 2009
    #6
    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"
     
  7. thread starter macrumors newbie

    Joined:
    Apr 28, 2009
    Location:
    Wiltshire, UK
    #7
    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?
     
  8. macrumors 65816

    mysterytramp

    Joined:
    Jul 17, 2008
    Location:
    Maryland
    #8
    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:

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

    Code:
    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
     
  9. thread starter macrumors newbie

    Joined:
    Apr 28, 2009
    Location:
    Wiltshire, UK
    #9
    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.
     
  10. macrumors 65816

    mysterytramp

    Joined:
    Jul 17, 2008
    Location:
    Maryland
    #10
    yes, you'll want to add:

    Code:
    do shell script testString
    
    You might also try single quotes instead of double quotes.

    Code:
    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
     
  11. thread starter macrumors newbie

    Joined:
    Apr 28, 2009
    Location:
    Wiltshire, UK
    #11
    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.

    Code:
    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:

    Code:
    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...

    Code:
    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:

    Code:
    tell current application
    	ASCII character 3
    		""
    	do shell script "echo -e \"C\" > /dev/cu.usbserial-000012FD"
    		""
    end tell
    
    MT's next suggestion was...

    Code:
    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:

    Code:
    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:

    Code:
    echo -e "C\x03" > /dev/cu.usbserial-000012FD
    I just need to replicate this in Applescript. Any other suggestions guys?
     
  12. ncl
    macrumors member

    Joined:
    Aug 16, 2008
    #12
    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:
    Code:
    set testString to "echo -e 'C" & (ASCII character (92)) & "x03' | hexdump -C"
    do shell script testString
    
    And here is the result:
    Code:
    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:
    Code:
    set testString to "echo 'C" & (ASCII character (92)) & "x03' | hexdump -C"
    do shell script testString
    
    I get:
    Code:
    00000000	43 03 0a	|C..|
    
    Which looks like what you want.
     
  13. thread starter macrumors newbie

    Joined:
    Apr 28, 2009
    Location:
    Wiltshire, UK
    #13
    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:

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

Share This Page