3

I am working with VMD (a molecular dynamics visualization package) and I want to open VMD from a Perl script, run a Tcl script, print the output to a log file, then close VMD and return to the Perl script. The ordinary syntax to do this is:

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

which breaks down as follows, as best as I understand:

  • system("");: executes Bourne Shell commands contained in quotes
  • vmd: calls VMD
  • -dispdev text: opens VMD in text mode
  • -eofexit: terminates VMD when EOF on STDIN is reached
  • < prog.tcl: sets prog.tcl as STDIN; vmd will terminate when prog.tcl completes
  • > LOG: writes STOUT to file <LOG>

Now this would work perfectly, except that my Tcl script takes arguments. What I'd like to do is something like:

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

however, in this case the shell tries to read string1 and string2 as files. With my limited understanding of redirection, I'm not sure exactly what is going in the first line, what exactly goes wrong in the second, or what a good solution would be. Any help would be appreciated.

3 Answers 3

2

Sorry, don't think you can pass arguments to your Tcl script directly when its being executed within another program like vmd. I would suggest passing the parameters via a file as a workaround. Eg. In the Perl script, before calling vmd, write the parameters to a file in Tcl syntax:

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

Then at the start of program.tcl, instead of using command line arguments ($argv), have it read the parameter file to pick up the argument values:

source myparams.tcl
Sign up to request clarification or add additional context in comments.

1 Comment

Perfect, I didn't know source. I have the VMD command running inside a loop, and I thought I was going to have to rewrite the entire Tcl script each time; this is much better. Too bad there's no way to pass the arguments directly though.
1

You can pass the arguments directly to VMD by doing something like

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

Make sure to add a quit statement at the end of program.tcl.

Comments

0

What you're doing is sending the contents of the program.tcl file to vmd, not the output of executing the program. If I understand you, you want to connect the Tcl program to vmd with a pipe:

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

Edit:

So, if vmd reads Tcl code on stdin, you can still pass parameters without using a temp file:

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

or

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...';

1 Comment

In that case, the shell would attempt to execute program.tcl as a shell command. If I piped ./program.tcl arg1 arg2 to VMD it would only send the output.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.