我正在使用VMD(分子动力学可视化包),我想从Perl脚本打开VMD,运行Tcl脚本,将输出打印到日志文件,然后关闭VMD并返回到Perl脚本。执行此操作的普通语法是:
system("vmd -dispdev text -eofexit < program.tcl > LOG");
按照我的理解分解如下:
system("");
:执行引号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作为文件读取。由于我对重定向的理解有限,我不确定完全第一行发生了什么,第二行究竟出了什么问题,或者什么是好的解决方案。任何帮助将不胜感激。
答案 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)
您可以通过执行类似
之类的操作将参数直接传递给VMDsystem(vmd -dispdev text -e program.tcl -args string1 string2 > LOG);
请务必在quit
的末尾添加program.tcl
语句。