如何抑制进程';tcl提示符中的s返回值

如何抑制进程';tcl提示符中的s返回值,tcl,return-value,Tcl,Return Value,我在TCL中是比较新的,在TCL提示符中,当我们调用一个带有返回值的proc时,该proc的返回值会被TCL回显。例如,有没有一种方法可以阻止它(而不影响看跌期权或类似功能) bash$ tclsh % proc a {} { puts "hello"; return 34; } % a hello 34 % 现在,如何抑制屏幕上的34?感谢您的帮助 更新: 实际上,proc是另一个工具的一部分,之前它没有任何返回值,但现在它可以有条件地返回值。 它可以从脚本中调用,不会有任何问题(正如Br

我在TCL中是比较新的,在TCL提示符中,当我们调用一个带有返回值的proc时,该proc的返回值会被TCL回显。例如,有没有一种方法可以阻止它(而不影响看跌期权或类似功能)

bash$ tclsh
% proc a {} { puts  "hello"; return 34; }
% a
hello
34
%
现在,如何抑制屏幕上的34?感谢您的帮助

更新: 实际上,proc是另一个工具的一部分,之前它没有任何返回值,但现在它可以有条件地返回值。 它可以从脚本中调用,不会有任何问题(正如Bryan指出的)。它可以从交互式提示符调用,然后在所有必要的输出之后,返回值被不必要地打印出来。 因此1)我没有能力更改用户的tclshrc 2)现有脚本应该继续工作。
奇怪的是,每次调用proc时,在所有必要的输出之后,都会打印一个数字。对于用户来说,这是一个不必要的信息,除非他已经抓住了价值并想做些什么。所以我希望将值传递给用户,但不需要打印到提示符/UI(希望我清楚)

您可以在.tclshc中创建一个空过程

proc void {} {}

…当您不需要返回值时,请以
结束该行;void

tclsh
wish
中的交互式shell代码将打印任何非空结果。要不打印任何内容,必须让“行”上的最后一个命令生成空结果。但是使用哪个命令呢

许多命令将产生空结果:

if 1 {}
subst ""
format ""
然而,最短的可能是:

list
因此,您可以编写如下代码:

a;list
当然,只有当您的命令实际生成了您不想看到的大型结果时,这才真正有用。在这些情况下,我经常发现使用测量结果大小的工具是最有用的,例如:

set tmp [something_which_produces a_gigantic result]; string length $tmp
我发现最有用的命令是
string length
llelength
dict size


如果绝对不能打印命令的结果,则必须编写自己的交互式循环。根据您是否在事件循环内运行,有两种方法可以执行此操作:

没有事件循环 这个过于简单的版本只是检查命令名是否与用户键入的内容一致。否则,任意丢弃结果可能不是一个好主意

set accum ""
while {[gets stdin line] >= 0} {
    append accum $line "\n"
    if {[info complete $accum]} {
        if {[catch $accum msg]} {
            puts stderr $msg
        } elseif {$msg ne "" && ![string match *TheSpecialCommand* $accum]} {
            puts $msg
        }
        set accum ""
    }
}
使用事件循环 这只是处理阻塞IO的情况;当输入来自一个煮熟的终端(即默认值)时,这是正确的


要清楚的是,我永远不会在我自己的代码中这样做!如果重要的话,我会手动抑制输出。

使用tcl\u interactive变量来启用值的返回,尽管我不确定这在哪里有用

proc a {} {
    puts "hello"
    if { [info exist tcl_interactive] } {
        return {};
    } else {
        return 34;
    }
} 

我认为没有办法做到这一点。为什么要禁用它?为什么这很重要?您是否知道这是交互式shell的一个功能,而在运行基于文件的脚本时您不会注意到这一点?Tcsh就是这样工作的。更改C源代码,构建一个没有这种行为的tclsh,并将其作为替代tclsh提供给用户。一个变色龙问题。您刚刚取消了大多数答案的资格。set命令的结果是新值<代码>设置a[设置b[设置c 34]将a、b和c设置为34。通过一些技巧(),它可以返回与
a
结果不同的值。如果需要,还可以编写自己的read-eval-print循环(不带打印部分)。这比通常合理的工作要多。根据我的更新,我必须默默地传递返回值。因此,即使我在最初的过程中写了一个包装,它也无法达到目的。@abasu对人的要求进行如此大的改变(改为问另一个问题!)并不好,但我希望我的扩展答案能够解决如何做到这一点。请注意,您必须使用自己的交互循环来执行这种技巧。(执行跟踪只能通过抛出错误来更改命令的输出,您可能不想这样做!)我理解最初的问题描述是不充分的。事实上,我认为这将是一个简单的设置一些冗长的水平。在第一批帖子之后,我理解了错误并更新了描述。无论如何,谢谢你的帖子。对我来说,这似乎是最好的/唯一的方法(除非我更改c代码并构建另一个tclsh:),您不应该只检查变量是否存在
tcl\u interactive
在他的情况下总是
1
。考虑使用<代码>信息级别< /代码> too.根据我的更新,我需要静默传递返回值。所以,即使是交互模式,我也需要一个返回值,我不想让tcl提示符回显这个值value@abasu:好的,我认为您只需要在非交互方式下使用返回值。因此,使用tcl提示符是您标准工作过程的一部分…@Kuhn:我已经通过在shell中运行它(顶部为#!/usr/bin/tclsh)和作为源命令的一部分运行它来检查了这一点。为此目的,它是有效的。
trace add execution TheSpecialCommand enter SuppressOutput
proc SuppressOutput args {
    # Important; do not suppress when it is called inside another command
    if {[info level] == 1} {
        set ::SuppressTheOutput 1
    }
}

# Mostly very similar from here on
set accum ""
while {[gets stdin line] >= 0} {
    append accum $line "\n"
    if {[info complete $accum]} {
        set SuppressTheOutput 0;                       # <<<<<< Note this!
        if {[catch $accum msg]} {
            puts stderr $msg
        } elseif {$msg ne "" && !$SuppressTheOutput} { # <<<<<< Note this!
            puts $msg
        }
        set accum ""
    }
}
proc a {} {
    puts "hello"
    if { [info exist tcl_interactive] } {
        return {};
    } else {
        return 34;
    }
}