我目前正在使用Tcl / Tk包装一个命令行工具(espeak
),到目前为止我已经想到了这个:
load ./extensions/system.so
package require Tk
package require Tclx
set chid 0
proc kill {id} {
exec kill -9 $id
}
proc speak {} {
global chid
set chid [fork]
if {$chid == 0} {
execvp espeak [.text get 1.0 end]
}
}
proc silent {} {
global chid
kill $chid
}
如果system.so是一个扩展程序,我一起攻击以便能够使用execvp
:
#include <tcl.h>
#include <tclExtend.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
static int
execvp_command(ClientData cdata, Tcl_Interp *interp, int argc, const char* argv[])
{
if (argc == 1)
{
interp->result = "execvp command ?args ...?";
return TCL_ERROR;
}
execvp(argv[1], argv + 1);
return TCL_OK;
}
int System_Init(Tcl_Interp* interp)
{
if (Tcl_InitStubs(interp, "8.1", 0) == NULL)
return TCL_ERROR;
Tcl_CreateCommand(interp, "execvp", execvp_command, NULL, NULL);
Tcl_PkgProvide(interp, "system", "1.0");
return TCL_OK;
}
我需要execvp
的原因是因为exec
(Tcl)创建的子流程似乎在流程终止时继续运行(我可以通过^C
确认这一点GUI),如果我使用execvp
,espeak
会正常死亡。
因此,所有我真正需要在这个脚本之外的是能够启动子进程并根据需要终止它。
是否有另一个可以正常执行此操作的库,例如Expect?
答案 0 :(得分:2)
Tcl在内部使用execvp
(真的;我刚检查了源代码),所以区别在于其他地方。其他地方将是信号;由exec
命令创建的子进程(以及使用相同底层引擎的其他东西)将使大多数信号被迫使用默认信号处理程序,但由于它设置为非默认值的唯一信号是SIGPIPE,我想知道还有什么。
尽管如此,处理这类事情的最终扩展是TclX。这使您可以访问部分使用的所有低级POSIX功能。 (期望也可以这样做。)