At this link I've read the for loop management for except https://tcl.tk/man/tcl8.6/TclCmd/for.htm
If you call expect and paste the code in in you get the correct behavoir :
@gigi:~$ expect
expect1.1> for {set x 0} {$x<10} {incr x} {
puts "x is $x"
}+> +>
x is 0
x is 1
x is 2
x is 3
x is 4
x is 5
x is 6
x is 7
x is 8
x is 9
expect1.2>
Instead if you pass it from bash script it goes to error:
^@gigi:~expect -d << EOD
> for {set x 0} {$x<10} {incr x} {
> puts "x is $x"
> }
> EOD
expect version 5.45.4
argv[0] = expect argv[1] = -d
set argc 0
set argv0 "expect"
set argv ""
executing commands from command file
missing operand at _@_
in expression "_@_<10"
(parsing expression "<10")
invoked from within
"for {set x 0} {<10} {incr x} {
puts "x is "
Why this example work different?
The problem you've got is that bash
has expanded the variables in the here-doc that you put the script in before passing it to expect
. From the bash
manpage:
The format of here-documents is:
[n]<<[-]word
here-document
delimiterNo parameter and variable expansion, command substitution, arithmetic expansion, or pathname expansion is performed on word. If any part of word is quoted, the delimiter is the result of quote removal on word, and the lines in the here-document are not expanded. If word is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion, the character sequence \<newline> is ignored, and \ must be used to quote the characters \, $, and `.
This means that one workaround is to use expect -d << 'EOD'
instead of expect -d << EOD
.
expect -d << 'EOD'
for {set x 0} {$x<10} {incr x} {
puts "x is $x"
}
EOD
Another (inferior!) is to backslash-quote the $
characters; it's inferior because real expect scripts often contain their own backslashes and things can get very ugly and complicated. However, the best is to do this:
Put the expect script in its own file, say myfile.exp
, and call it like this: expect -d -f myfile.exp
. Trying to put Tcl code inside Bash scripts like that is asking for trouble.
Note that this does mean that passing variables from bash is a little more awkward. But you gain by the vastly increased sanity of coding.