如何使用“-c”选项将参数传递给 EXPECT?

Kat*_*tie 3 shell scripting bash shell-script expect

我通过 usingexpect在我的 bash 脚本中使用expect -c,但是如何将参数传递给它?

这是我尝试过的:

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'
Run Code Online (Sandbox Code Playgroud)

如果我创建一个单独的具有相同内容的期望脚本,但在 bash 中像这样调用它:

myScript.expect $FILE $HOST
Run Code Online (Sandbox Code Playgroud)

它有效,但我如何做同样的事情但使用该expect -c选项?

更新:

还试过:

/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
Run Code Online (Sandbox Code Playgroud)

thr*_*rig 5

你不能。在源代码中,expect-5.45.4我们exp_main_sub.c在第 711 行找到

            case 'c': /* command */
                    exp_cmdlinecmds = TRUE;
                    rc = Tcl_Eval(interp,optarg);
                    ...
Run Code Online (Sandbox Code Playgroud)

它处理-c代码。$argv仅-c在第 850 行之后eval 完成后才创建朋友

    /* 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);
Run Code Online (Sandbox Code Playgroud)

所以$argv在-c代码运行时绝对不存在。

一种解决方法是在远程服务器上运行本地期望脚本?这需要在标准输入上传递 TCL 代码,然后读expect入文件/dev/stdin

$ echo puts \[lindex \$argv 1\] | expect /dev/stdin blee bla blu
bla
Run Code Online (Sandbox Code Playgroud)

另一种解决方法是折腾外壳并在 TCL 中编写整个内容

#!/usr/bin/env expect
set FILE [lindex $argv 0]
set HOST [lindex $argv 1]
...
Run Code Online (Sandbox Code Playgroud)

然后chmod +x运行它

./whatyoucalledtheabove somefile somehost
Run Code Online (Sandbox Code Playgroud)

它需要包含您当前的 shell 脚本在expect调用之上执行的任何其他操作...