升级到Debian Jessie之后,我设置的tcl motd在登录(主机名消隐)时给了我一个奇怪的错误:
var products = [("Kayak","A boat for one person","Watersports",275.0,10),
("Lifejacket","Protective and fashionable","Watersports",48.95,14),
("Soccer Ball","FIFA-approved size and weight","Soccer",19.5,32),
("Corner Flags","Give your playing field a professional touch","Soccer",34.95,1),
("Stadium","Flat-packed 35,000-seat stadium","Soccer",79500.0,4),
("Improve your brain efficiency by 75%","Chess",16.0,8),
("Unsteady Chair","Secretly give your opponent a disadvantage","Chess",29.95,3),
("Human Chess Board","A fun game for the family","Chess",75.0,2),
("Bling-Bling King","Gold-plated,diamon-studded King","Chess",1200.0,4)]
我很困惑,因为我自己运行命令我得到了打印在顶部的确切行,但是当作为脚本的一部分运行时它不应该打印任何东西,而是将其设置为变量的值,如你可以从错误中引用的行看到:
root pts/0 XXXX-XX-XX-XXX-X Thu Jun 23 01:49:55 2016 - Thu Jun 23 01: 50:09 2016 (00:00)
child killed: write on pipe with no readers
while executing
"exec -- last -F | head -n 2 | tail -n 1 "
invoked from within
"set lastlog [exec -- last -F | head -n 2 | tail -n 1 ]"
(file "/etc/motd.tcl" line 24)
这里发生了什么导致了神秘的错误,我该如何解决?
答案 0 :(得分:3)
错误是由其中一个以非零退出代码(exec
非常敏感)终止的子进程引起的,而这又是由于尽管管道已关闭但仍然产生输出(使用head
的常见问题)。最简单的解决方法是将last -F
的整个输出读入Tcl并在那里进行线切割。幸运的是,这很容易:
set lastOutputLines [split [exec -- last -F] "\n"]
set lastlog [lindex $lastOutputLines 1]; # Zero-based indexing
只要last
的输出不是很大,这就足够了。
答案 1 :(得分:1)
您可以使用子shell调用,其中shell不介意第一个按信号终止的命令,如:
set lastlog [exec -- bash -c "last -F | head -n 2 | tail -n 1"]
这具有实际终止" last"的执行的优点。在它发出整个输出之前,如果输出很长就很好。