Bash TCL脚本以“中断”;儿童被杀:在没有读者的管道上写字”;

Bash TCL脚本以“中断”;儿童被杀:在没有读者的管道上写字”;,bash,debian,tcl,Bash,Debian,Tcl,升级到Debian Jessie后,我设置的tcl motd在登录时给了我一个奇怪的错误(主机名消失): 我感到困惑,因为我自己运行该命令时会得到打印在顶部的确切行,但作为脚本的一部分运行时,它不应该打印任何内容,而是将其设置为变量的值,从错误中的引用行可以看出: set lastlog [exec -- last -F | head -n 2 | tail -n 1 ] 这里发生的是什么导致了这个神秘的错误?我如何修复它?这个错误是由一个子进程以一个非零出口代码终止而引起的(这个非零出口代码

升级到Debian Jessie后,我设置的tcl motd在登录时给了我一个奇怪的错误(主机名消失):

我感到困惑,因为我自己运行该命令时会得到打印在顶部的确切行,但作为脚本的一部分运行时,它不应该打印任何内容,而是将其设置为变量的值,从错误中的引用行可以看出:

set lastlog [exec -- last -F | head -n 2 | tail -n 1 ]

这里发生的是什么导致了这个神秘的错误?我如何修复它?

这个错误是由一个子进程以一个非零出口代码终止而引起的(这个非零出口代码对exec非常敏感),而这个非零出口代码又是由它在关闭管道的情况下仍有输出来产生的(使用
head
)的一个常见问题。最简单的修复方法是将
last-F
的整个输出读入Tcl并在那里进行断线。幸运的是,这很容易:

set lastOutputLines [split [exec -- last -F] "\n"]
set lastlog [lindex $lastOutputLines 1]; # Zero-based indexing

只要
last
的输出不是很大,这就足够快了。

您可以使用子shell调用,其中shell不介意第一个命令通过信号终止,如:

set lastlog[exec--bash-c“last-F | head-n2 | tail-n1”]


这样做的好处是,在“last”发出整个输出之前,它实际上终止了“last”的执行,如果输出很长的话,这很好。

我在我的Ubuntu中尝试过,这个命令运行良好。
set lastOutputLines [split [exec -- last -F] "\n"]
set lastlog [lindex $lastOutputLines 1]; # Zero-based indexing