【问题标题】:Problem executing TCL script from Bourne Shell (redirection trouble)从 Bourne Shell 执行 TCL 脚本时出现问题(重定向问题)
【发布时间】:2010-11-14 14:02:58
【问题描述】:

我正在使用 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
  • &lt; prog.tcl:将prog.tcl 设置为标准输入; vmd 将在prog.tcl 完成时终止
  • &gt; LOG:将 STOUT 写入文件 &lt;LOG&gt;

现在这将完美地工作,除了我的 Tcl 脚本需要参数。我喜欢做的是这样的:

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

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

【问题讨论】:

    标签: shell redirect tcl arguments


    【解决方案1】:

    抱歉,当 Tcl 脚本在另一个程序(如 vmd)中执行时,您不能直接将参数传递给您的 Tcl 脚本。我建议通过文件传递参数作为解决方法。例如。 在 Perl 脚本中,在调用 vmd 之前,将参数写入 Tcl 语法的文件中:

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

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

    source myparams.tcl
    

    【讨论】:

    • 完美,我不知道source。我在循环中运行了 VMD 命令,我想我每次都必须重写整个 Tcl 脚本;这好多了。可惜没有办法直接传递参数。
    【解决方案2】:

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

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

    编辑:

    因此,如果 vmd 读取标准输入上的 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...';
    

    【讨论】:

    • 在这种情况下,shell 会尝试将program.tcl 作为 shell 命令执行。如果我通过管道将./program.tcl arg1 arg2 发送到 VMD,它只会发送输出。
    【解决方案3】:

    您可以通过执行类似的操作将参数直接传递给 VMD

    system(vmd -dispdev text -e program.tcl -args string1 string2 > LOG);
    

    确保在program.tcl 末尾添加quit 语句。

    【讨论】:

      猜你喜欢
      • 2020-10-28
      • 2010-10-11
      • 1970-01-01
      • 2018-09-12
      • 2012-02-18
      • 2020-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多