从Bourne Shell执行TCL脚本时出现问题(重定向问题)

时间:2009-07-28 04:37:26

标签: shell redirect tcl arguments

我正在使用VMD(分子动力学可视化包),我想从Perl脚本打开VMD,运行Tcl脚本,将输出打印到日志文件,然后关闭VMD并返回到Perl脚本。执行此操作的普通语法是:

system("vmd -dispdev text -eofexit < program.tcl > LOG");

按照我的理解分解如下:

  • system("");:执行引号
  • 中包含的Bourne Shell命令
  • vmd:调用VMD
  • -dispdev text:以文本模式打开VMD
  • -eofexit:在达到STDIN上的EOF时终止VMD
  • < prog.tcl:将prog.tcl设为STDIN; vmd将在prog.tcl完成时终止
  • > LOG:将STOUT写入文件<LOG>

现在这可以完美地工作,除了我的Tcl脚本接受参数。我喜欢做的事情就像:

system("vmd -dispdev text -eofexit < program.tcl string1 string2 > LOG");

但是,在这种情况下,shell会尝试将string1和string2作为文件读取。由于我对重定向的理解有限,我不确定完全第一行发生了什么,第二行究竟出了什么问题,或者什么是好的解决方案。任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:1)

抱歉,当你的Tcl脚本在vmd等其他程序中执行时,不要认为你可以直接将参数传递给它。我建议通过文件传递参数作为解决方法。例如。 在Perl脚本中,在调用vmd之前,使用Tcl语法将参数写入文件:

open PARAMS, '>myparams.tcl';
print PARAMS "set arg1 $string1; set arg2 $string2";
close PARAMS;

然后在program.tcl的开头,不是使用命令行参数($ argv),而是让它读取参数文件以获取参数值:

source myparams.tcl

答案 1 :(得分:0)

您正在做的是将program.tcl文件的内容发送到vmd,而不是执行程序的输出。如果我理解你,你想用管道将Tcl程序连接到vmd:

system("program.tcl arg1 arg2 | vmd -... > output.file");

修改

因此,如果vmd在stdin上读取Tcl代码,您仍然可以在不使用临时文件的情况下传递参数:

system("( echo 'set arg1 str1; set arg2 str2'; cat program.tcl; ) | vmd ... > output_file");

open my $fh, '<', 'program.tcl';
my @tcl = <$fh>;
close $fh;
unshift @tcl, "set arg1 str1\n", "set arg2 str2\n";
open $fh, '|-', 'vmd ... > output.file' or die 'msg...';
print $fh join('', @tcl);
close $fh or die 'msg...';

答案 2 :(得分:0)

您可以通过执行类似

之类的操作将参数直接传递给VMD
system(vmd -dispdev text -e program.tcl -args string1 string2 > LOG);

请务必在quit的末尾添加program.tcl语句。