英文:
how to pass arguments to expect -c script?
问题
抱歉,我不能执行代码。如果你有关于代码的问题或需要帮助,我可以提供一般性的建议和指导。
英文:
I want to run a temporary expect script with arguments and leave stdin open:
expect -c 'spawn {*}$argv' /dev/null echo hello world
However this results in
can't read "argv": no such variable
while executing
"spawn {*}$argv"
How do I execute it?
答案1
得分: 1
请查看args解析的源代码:
656 void
657 exp_parse_argv(interp, argc, argv)
658 Tcl_Interp *interp;
659 int argc;
660 char **argv;
661 {
...
703 while ((c = getopt(argc, argv, "+b:c:dD:f:inN-v")) != EOF) {
704 switch(c) {
...
711 case 'c': /* command */
712 exp_cmdlinecmds = TRUE;
713 rc = Tcl_Eval(interp, optarg);
714 if (rc != TCL_OK) {
715 expErrorLogU(exp_cook(Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY), (int *)0));
716 expErrorLogU("\r\n");
717 }
718 break;
...
773 }
...
850 /* 收集剩余的参数并形成 argc、argv0 和 argv */
851 sprintf(argc_rep, "%d", argc - optind);
852 Tcl_SetVar(interp, "argc", argc_rep, 0);
853 expDiagLog("set argc %s\r\n", argc_rep);
854
855 if (exp_cmdfilename) {
856 Tcl_SetVar(interp, "argv0", exp_cmdfilename, 0);
857 expDiagLog("set argv0 \"%s\"\r\n", exp_cmdfilename);
858 } else {
859 Tcl_SetVar(interp, "argv0", exp_argv0, 0);
860 expDiagLog("set argv0 \"%s\"\r\n", exp_argv0);
861 }
862
863 args = Tcl_Merge(argc - optind, argv + optind);
864 expDiagLogU("set argv \"");
865 expDiagLogU(args);
866 expDiagLogU("\"\r\n");
867 Tcl_SetVar(interp, "argv", args, 0);
868 Tcl_Free(args);
869
870 exp_interpret_rcfiles(interp, my_rc, sys_rc);
871 }
它按照以下顺序运行:
- 在
while
循环的第703行,使用-c command
(第711行)通过Tcl_Eval()
(第713行)运行。 - 第852行设置了 Tcl 的变量
argc
。 - 第856/859行设置了
argv0
。 - 第867行设置了
argv
。
因此,当运行 -c command
时,argv0/argc/argv
还不可用。
这也可以通过 expect -d
显示:
$ expect -d -c 'puts "now in -c command" ' /dev/null foo bar
expect 版本 5.45
now in -c command <====
argv[0] = expect argv[1] = -d argv[2] = -c argv[3] = puts "now in -c command"
argv[4] = /dev/null argv[5] = foo argv[6] = bar
set argc 2 <====
set argv0 "/dev/null" <====
set argv "foo bar" <====
正在执行来自命令文件 /dev/null 的命令
英文:
See the source code for args parsing:
656 void
657 exp_parse_argv(interp,argc,argv)
658 Tcl_Interp *interp;
659 int argc;
660 char **argv;
661 {
...
703 while ((c = getopt(argc, argv, "+b:c:dD:f:inN-v")) != EOF) {
704 switch(c) {
...
711 case 'c': /* command */
712 exp_cmdlinecmds = TRUE;
713 rc = Tcl_Eval(interp,optarg);
714 if (rc != TCL_OK) {
715 expErrorLogU(exp_cook(Tcl_GetVar(interp,"errorInfo",TCL_GLOBAL_ONLY),(int *)0));
716 expErrorLogU("\r\n");
717 }
718 break;
...
773 }
...
850 /* collect remaining args and make into argc, argv0, and argv */
851 sprintf(argc_rep,"%d",argc-optind);
852 Tcl_SetVar(interp,"argc",argc_rep,0);
853 expDiagLog("set argc %s\r\n",argc_rep);
854
855 if (exp_cmdfilename) {
856 Tcl_SetVar(interp,"argv0",exp_cmdfilename,0);
857 expDiagLog("set argv0 \"%s\"\r\n",exp_cmdfilename);
858 } else {
859 Tcl_SetVar(interp,"argv0",exp_argv0,0);
860 expDiagLog("set argv0 \"%s\"\r\n",exp_argv0);
861 }
862
863 args = Tcl_Merge(argc-optind,argv+optind);
864 expDiagLogU("set argv \"");
865 expDiagLogU(args);
866 expDiagLogU("\"\r\n");
867 Tcl_SetVar(interp,"argv",args,0);
868 Tcl_Free(args);
869
870 exp_interpret_rcfiles(interp,my_rc,sys_rc);
871 }
It runs in this order:
- Line 703, in the
while
loop,-c command
(line 711) is run withTcl_Eval()
(line 713). - Line 852 sets Tcl's var
argc
. - Line 856/859 sets
argv0
. - Line 867 sets
argv
.
So when -c command
is run, argv0/argc/argv
are not yet available.
This can also be shown with expect -d
:
$ expect -d -c 'puts "now in -c command" ' /dev/null foo bar
expect version 5.45
now in -c command <====
argv[0] = expect argv[1] = -d argv[2] = -c argv[3] = puts "now in -c command"
argv[4] = /dev/null argv[5] = foo argv[6] = bar
set argc 2 <====
set argv0 "/dev/null" <====
set argv "foo bar" <====
executing commands from command file /dev/null
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论