如何从 tcl 脚本调用 bash 命令?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4116903/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 22:52:38  来源:igfitidea点击:

How to call bash commands from tcl script?

bashexectclinteractive

提问by Vahagn

Bash commands are available from an interactive tclsh session. E.g. in a tclsh session you can have

Bash 命令可从交互式 tclsh 会话中获得。例如,在 tclsh 会话中,您可以拥有

% ls

instead of

代替

$ exec ls

However, you cant have a tcl script which calls bash commands directly (i.e. without exec).

但是,您不能拥有直接调用 bash 命令的 tcl 脚本(即没有exec)。

How can I make tclsh to recognize bash commands while interpreting tcl script files, just like it does in an interactive session?

如何让 tclsh 在解释 tcl 脚本文件时识别 bash 命令,就像在交互式会话中一样?

I guess there is some tcl package (or something like that), which is being loaded automatically while launching an interactive session to support direct calls of bash commans. How can I load it manually in tcl script files?

我猜有一些 tcl 包(或类似的东西),它在启动交互式会话时自动加载以支持直接调用 bash 命令。如何在 tcl 脚本文件中手动加载它?

回答by Donal Fellows

If you want to have specificutilities available in your scripts, write bridging procedures:

如果您想在脚本中使用特定的实用程序,请编写桥接过程:

proc ls args {
    exec {*}[auto_execok ls] {*}$args
}

That will even work (with obvious adaptation) for most shell builtins or on Windows. (To be fair, you usually don't want to use an external ls; the internal globcommand usually suffices, sometimes with extra help from some filesubcommands.) Some commands need a little more work (e.g., redirecting input so it comes from the terminal, with an extra <@stdinor </dev/tty; that's needed for sttyon some platforms) but that works reasonably well.

对于大多数 shell 内置程序或在 Windows 上,这甚至可以工作(有明显的适应)。(公平地说,您通常不想使用外部命令ls;内部glob命令通常就足够了,有时需要一些file子命令的额外帮助。)有些命令需要做更多的工作(例如,重定向输入使其来自终端,带有额外的<@stdin</dev/tty; 这stty在某些平台上是必需的)但效果相当好。

However, if what you're asking for is to have arbitrary execution of external programs without any extra code to mark that they are external, that's considered to be against the ethos of Tcl. The issue is that it makes the code quite a lot harder to maintain; it's not obvious that you're doing an expensive call-out instead of using something (relatively) cheap that's internal. Putting in the execin that case isn't thatonerous…

但是,如果您要求的是在没有任何额外代码来标记它们是外部程序的情况下任意执行外部程序,那么这被认为是违反 Tcl 的精神的。问题是它使代码更难维护;不明显的是,您正在进行昂贵的呼叫而不是使用内部的(相对)便宜的东西。在把exec在这种情况下是不是沉重的...

回答by SingleNegationElimination

What's going on here is that the unknownproc is getting invoked when you type a command like ls, because that's not an existing tcl command, and by default, that command will check that if the command was invoked from an interactive session and from the top-level (not indirectly in a proc body) and it's checking to see if the proc name exists somewhere on the path. You can get something like this by writing your own proc unknown.

这里发生的事情是,unknown当您键入诸如 之类的命令时会调用 proc ls,因为这不是现有的 tcl 命令,并且默认情况下,该命令将检查该命令是否是从交互式会话和顶层调用的(不是间接在 proc 主体中)并且它正在检查 proc 名称是否存在于路径上的某处。您可以通过编写自己的未知过程来获得类似的结果。

For a good start on this, examine the output of

为了对此有一个良好的开端,请检查输出

info body unknown

回答by Paused until further notice.

One thing you should know is that lsis not a Bash command. It's a standalone utility. The clue for how tclsh runs such utilities is right there in its name - shmeans "shell". So it's the rough equivalent to Bash in that Bash is also a shell. Tcl != tclsh so you have to use exec.

您应该知道的一件事是它ls不是 Bash 命令。它是一个独立的实用程序。tclsh 如何运行这些实用程序的线索就在它的名字中——sh意思是“shell”。所以它大致相当于 Bash,因为 Bash 也是一个 shell。Tcl != tclsh 所以你必须使用exec.