2

I'm trying to write an expect script, which is based on Tcl. (actually I'm trying to generate expect scripts in python, and no, I can't use pyexpect)

How can I send a string without special characters (like [) being interpreted as commands?

In bash shell, I can use single quotes to write raw strings.

$ echo 'hello $world'
hello $world

But with expect, I have many problems with special characters. For example, brackets are interpreted as commands.

expect1.1> send_user "[hello]"
invalid command name "hello"
    while executing
"hello"

How can I just print the string "[hello]"?

EDIT: just enclosing a string in curly braces doesn't always work.

For example

expect1.4> send_user {h}ello}

doesn't print the string "h}ello". It gives an error:

extra characters after close-brace
    while executing
"send {h}ello}

And there is no way to escape the curly braces according to the doc.

Or what if I want to send a string starting with *} ? Rule 5 in http://tcl.tk/man/tcl8.5/TclCmd/Tcl.htm#M10 will interfere and no way to escape the * or the }.

John Smith Optional
  • 22,259
  • 12
  • 43
  • 61

1 Answers1

4

Curly braces inhibit all expansion*:

echo {hello $world}

You could also just escape the brackets:

Echo "hello \$world"
  • Curly braces inhibit all expansion when the statement is parsed. However, some commands may choose to do their own expansion internally. The if statement is one such command -- even with curly braces variables will get expanded. Not many commands have this behavior, though.

This is all documented in the Tcl man page. Here's a link to the section on curly braces: http://tcl.tk/man/tcl8.5/TclCmd/Tcl.htm#M10

You might also be interested in this question on stackoverflow: General string quoting for Tcl

Note that curly braces aren't magic -- you still have to apply the quoting rules. For example, you can't have unbalanced curly braces, etc. the precise quoting mechanism you need will vary depending on the data. For some strings that means curly braces, for some it means quotes, for others you might need the backslash. For still others you may need a combination along with string concatenation.

Community
  • 1
  • 1
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • Ok thanks. It makes the code very difficult to read when using expect. Expect uses curly braces too for delimiting possibles patterns and corresponding actions. – John Smith Optional Apr 30 '14 at 20:41
  • Well, actually that doesn't work. I add the problematic strings to my question. – John Smith Optional May 01 '14 at 12:28
  • Your "problematic string" is different than the original question. Yes, strings with unbalanced curly braces will yield the new problem you are seeing. You asked how to avoid command expansion, now how to avoid using unbalanced curly braces. If you have the string `h}ello`, use double quotes. If your real string is an ungodly mix of multiple special characters you will have to get creative. There is no one perfect way to quote every possible string. – Bryan Oakley May 01 '14 at 12:41
  • 1
    Thanks for the quick reply. I'm looking for a way to send a string as is. These expect scripts are generated in a python script and yes, the real strings could be any kind of mix of multiple special characters. You answered the original question well, so maybe I should start another topic. On the other side, I think a lot of people reading this question will be looking for a general procedure to quote strings that contain special characters. At least I am. – John Smith Optional May 01 '14 at 12:46
  • @JohnSmithOptional: expect adds no special behavior to curly braces. It uses them just like any other tcl code. Nothing in tcl _ever_ requires you use curly braces. There are certainly best practices, and curly braces are often the most practical choice, but tcl and expect behave identically in this regard. – Bryan Oakley May 01 '14 at 12:48
  • My problem is actually to generate an expect command from an arbitrary string in python. `mycommand = "send {%s}" % string_to_send` doesn't work if `string_to_send` contains a curly brace and I don't see any way of quoting the curly braces. – John Smith Optional May 01 '14 at 12:54
  • @JohnSmithOptional: if that's your real problem, you should have asked about that. That is a completely different problem. – Bryan Oakley May 01 '14 at 12:57
  • Well, in most programming languages, that wouldn't be a different problem. For example, in bash, as soon as I know that I can print raw strings by enquoting them in single quotes and escaping the single quotes, I know immediately how to do it programmatically within another language. – John Smith Optional May 01 '14 at 13:01
  • the best way to is to use `list`, which will appropriate quote the input. – Johannes Kuhn May 01 '14 at 14:01
  • @JohannesKuhn: true, but the OP in a comment said they are trying to build this string in python. Though, perhaps the OP could leverage the embedded tcl interpreter that comes with Tkinter to do that. – Bryan Oakley May 01 '14 at 14:04