Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
“Tcl期望”;“互动”;命令回显生成的rlwrap进程的先前输出_Tcl_Expect - Fatal编程技术网

“Tcl期望”;“互动”;命令回显生成的rlwrap进程的先前输出

“Tcl期望”;“互动”;命令回显生成的rlwrap进程的先前输出,tcl,expect,Tcl,Expect,我有一种感觉,我显然遗漏了一些东西,但我的搜索到目前为止毫无结果 我正在尝试使用tcl/expect脚本启动一个tclsh交互式shell,添加一个过程,以便轻松地重新加载实用程序进行测试,然后将正常控制返回给我 到目前为止,我发现使tcl交互式shell“可用”的一种方法是以“rlwrap”开头,这样我就可以使用箭头键等 因此,我尝试了下面的脚本,关于rlwrap的一些内容导致在点击interact命令时将以前的输出转储到stdout 我能做些什么来避免这种情况发生吗 代码: 输出: Tcl

我有一种感觉,我显然遗漏了一些东西,但我的搜索到目前为止毫无结果

我正在尝试使用tcl/expect脚本启动一个tclsh交互式shell,添加一个过程,以便轻松地重新加载实用程序进行测试,然后将正常控制返回给我

到目前为止,我发现使tcl交互式shell“可用”的一种方法是以“rlwrap”开头,这样我就可以使用箭头键等

因此,我尝试了下面的脚本,关于rlwrap的一些内容导致在点击interact命令时将以前的输出转储到stdout

我能做些什么来避免这种情况发生吗

代码:

输出:

Tcl version   : 8.4
Expect version: 5.43.0

Use 'reload' procedure to re-source utility files


   proc reload {} {
      # Procedure to reload utility source easily for testing
   }
% reload
%  
您可能会发现,由于某种原因,它会回显proc定义和输入reload命令。一旦发生交互,就会发生这种情况。如果我用“exit”替换interact,我看不到任何输出

当然,我希望看到的结果是:

Tcl version   : 8.4
Expect version: 5.43.0

Use 'reload' procedure to re-source utility files

%  

您要做的是等待一个明确的标记,该标记指示从属进程已准备就绪

# ... your script as above ...
expect "% "

#### NEW STUFF STARTS ####
send "reload;puts READY\r"
expect "READY\r"

# Note that we need to fake the prompt; c'est la vie
send_user "\nUse 'reload' procedure to re-source utility files\n\n% "

# Now start doing things!
log_user 1
interact

或者至少当我尝试使用从属进程时,这是可行的,但我没有在混合中使用rlwrap,因此可能会改变情况…

如果您不介意自己编译一个小型C程序,您可以使用以下方法:

#包括
#ifdef WIN32
#ifdef UNICODE
#定义WIN32_UNICODE
#恩迪夫
#恩迪夫
国际铁路干线(Tcl_Interp*);
静态int g_argc;
#ifdef WIN32_UNICODE
#定义Tcl_NewStringObj Tcl_newunicodebj
静态wchar\u t***g\u argv;
无效wmain(内部argc,wchar\u t**argv){
#否则
静态字符***g_argv;
void main(整型argc,字符**argv){
#恩迪夫
g_argc=argc;
g_argv=&argv;
Tcl_FindExecutable(argv[0]);
Tcl_干管(1号,argv,TCLShiu干管);
}
int TclSHI_Main(Tcl_Interp*Interp){
Tcl_Obj*lobj;
int i;
如果(g_argc>1){
Tcl_SetVar2Ex(interp,“argv0”,NULL,Tcl_NewStringObj((*g_argv)[1],-1),仅Tcl_GLOBAL_);
}
lobj=Tcl_NewObj();
Tcl_IncrRefCount(lobj);
对于(i=2;i1){
Tcl_Eval(interp,“来源$argv0”);
}
返回TCL_OK;
}
我在windows(CL)和linux(GCC)上测试了它。
为了用gcc编译它,我使用了
gcc TclSH.c-o TclSHI-ltcl8.6

在windows上,我使用了Visual Studio

它告诉Tcl它没有收到任何参数(
Tcl_Main(1,…)
),但用这些参数填充新的interp并生成文件。在此步骤之后,它将始终显示提示(它从未收到任何参数,对吗?)

expect解决方案有一个小问题,如果指定任何参数,Tcl将执行该脚本,并且从不显示提示


还要注意的是,我是一个C程序员新手,所以这个解决方案可能不是防弹的。

试试
expect“%”
log\u user 1
伟大的建议之前,Glenn,但不幸的是,它似乎没有改变输出。在发送过程后,您不会发送回车。我尝试过,这似乎一点都不重要。不确定为什么,但它按预期工作(除了额外显示的输出)。一旦interact允许我进行控制,程序就可以正确定义和使用。唯一的其他方法是编写一个使用
Tcl_Main
的自定义C应用程序,或者自己编写输入/求值/输出循环。我相信我们需要
tclsh-interactive initscript.Tcl
可以使用
rlwrap tclsh-interactive initsccript.tcl
@JohannesKuhn,我实际上搜索了一个到tclsh的交互式开关,因为我认为必须有这样一个开关。唉,没有,但我同意当我只是一个带有init脚本的tclsh时,添加它以避免使用expect是一件很好的事情。@DonalFellows,我尝试了你的建议,它改变了行为,但没有修复它。现在的问题是,它的行为不一致…有时我看到过程定义,有时我看不到。我多次运行同一个脚本,但它的行为随机不同。起初我认为它有所改进,但它只是碰巧是一次迭代,没有输出过程定义。感谢代码Johannes。这就是这是一个可能的解决方法,我一定会研究。但对于这个问题,我仍然试图理解rlwrap和expect之间的问题。本质上,这是解决问题和真正理解问题之间的区别。你绝对正确,传递和争论是不起作用的。这这只是我为这篇文章推断的一个简单例子。我会编辑它,谢谢。
# ... your script as above ...
expect "% "

#### NEW STUFF STARTS ####
send "reload;puts READY\r"
expect "READY\r"

# Note that we need to fake the prompt; c'est la vie
send_user "\nUse 'reload' procedure to re-source utility files\n\n% "

# Now start doing things!
log_user 1
interact