简体   繁体   中英

sending non-printable characters in expect script

I found that when I use certain bytes as input to a program in an expect script, then there is an automatic conversion to multibytes when a byte is above 0x7f. For example the following line in the script:

spawn./myprog [exec perl -e { print "\x7f\x80" }]

sends actually three instead of two bytes to myprog: 0x7f 0xc2 0x80

myprog is a simple test program that prints the input it gets:

int main(int argc, char** argv) {
   int i;
   for (i=0;i<strlen(argv[1]);i++) {
      printf("%x\n", (unsigned char)argv[1][i]);
}

I understand that 0x7f is the magic boundary to unicode-related encodings, but how can I just send a byte like 0x80 to my program? In the expect script I already tried conversions like [encoding convertto iso8859-1 [exec perl...]] described in https://www.tcl.tk/doc/howto/i18n.html , but nothing works.

On the other hand, when I do the identical thing on the command line, eg:

./myprog `perl -e 'print "\x7f\x80"'`

I do get only two bytes - as expected (the differing {} compared to the expect script line is tcl's replacement of '').

How can I force the same behavior in an expect script?

After some more experimentation, I found that the only way to do that is to have the argument handover outside the expect logic, eg:

set input [binary format H* 7f80]
exec echo "$input" > input.dat
spawn sh -c "./myprog `cat input.dat`"

Note that using ${...} instead of backticks does not seem to work easily due to the special meaning of $ to expect.

Of course, having spawned a shell instead of the process directly is not the same thing but that does not matter for most of my use cases.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM