How to pass parameters to EXPECT using the '-c' option?

8,784

You cannot. In the source code for expect-5.45.4 we find in exp_main_sub.c at line 711

            case 'c': /* command */
                    exp_cmdlinecmds = TRUE;
                    rc = Tcl_Eval(interp,optarg);
                    ...

which handles -c code. $argv and friends are only created after the -c eval completes down at line 850 onwards

    /* collect remaining args and make into argc, argv0, and argv */
    sprintf(argc_rep,"%d",argc-optind);
    Tcl_SetVar(interp,"argc",argc_rep,0);
    expDiagLog("set argc %s\r\n",argc_rep);

    ...
    Tcl_SetVar(interp,"argv",args,0);

so $argv absolutely does not exist when the -c code runs.

One workaround is Run a local expect script on a remote server? which entails passing the TCL code in on standard input and then reading in expect the file /dev/stdin

$ echo puts \[lindex \$argv 1\] | expect /dev/stdin blee bla blu
bla

Another workaround is to toss the shell and write the whole thing in TCL

#!/usr/bin/env expect
set FILE [lindex $argv 0]
set HOST [lindex $argv 1]
...

And then chmod +x that and run it

./whatyoucalledtheabove somefile somehost

It would need to contain whatever else your current shell script does above the expect call...

Share:
8,784
Katie
Author by

Katie

Software Engineer specializing in everything web. These are a few of my favorite things: angular node.js javascript go python java c++ bash jquery katies.io

Updated on September 18, 2022

Comments

  • Katie
    Katie over 1 year

    I'm using expect inside my bash script by using expect -c, but how do I pass parameters to it?

    This is what I've tried:

    FILE="myFile"
    HOST="myhostname" 
    
    /usr/bin/expect -c $FILE $HOST '
            set FILE [lindex $argv 0];
            set HOST [lindex $argv 1];
            send_user "$FILE $HOST"
            spawn scp -r -o StrictHostKeyChecking=no  $FILE root@$HOST:/tmp/
            expect "assword:"
            send "password\r"
            interact'
    

    If I create a separate expect script with the same contents but call it in bash like this:

    myScript.expect $FILE $HOST
    

    It works, but how do I do the same thing but using the expect -c option?

    Update:

    Also tried:

    /usr/bin/expect -c '
            set FILE [lindex $argv 0];
            set HOST [lindex $argv 1];
            send_user "$FILE $HOST"
            spawn scp -r -o StrictHostKeyChecking=no  $FILE root@$HOST:/tmp/
            expect "assword:"
            send "password\r"
            interact' $FILE $HOST
    
    • Katie
      Katie about 6 years
      @steeldriver No, I'm getting can't read "argv": no such variable :(
  • Katie
    Katie about 6 years
    Bummer, alrighty I'll create a separate script and call that. Thank you for the detailed explanation!