Проблема при выполнении сценария TCL из Bourne Shell (проблема с перенаправлением)

Я работаю с VMD (пакет визуализации молекулярной динамики), и я хочу открыть VMD из сценария Perl, запустить сценарий Tcl, распечатать вывод в файл журнала, затем закрыть VMD и вернуться к сценарию Perl. Обычный синтаксис для этого:

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

который, насколько я понимаю, распадается следующим образом:

  • system("");: выполняет команды Bourne Shell, заключенные в кавычки
  • vmd: вызывает VMD
  • -dispdev text: открывает VMD в текстовом режиме
  • -eofexit: завершает VMD при достижении EOF на STDIN
  • < prog.tcl: устанавливает prog.tcl как STDIN; vmd прекратит работу, когда завершится prog.tcl
  • > LOG: записывает STOUT в файл <LOG>

Теперь это будет работать отлично, за исключением того, что мой сценарий Tcl принимает аргументы. Я бы хотел сделать что-то вроде:

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

однако в этом случае оболочка пытается прочитать строку 1 и строку 2 как файлы. С моим ограниченным пониманием перенаправления я не уверен в точности, что происходит в первой строке, что именно идет не так во второй или в каком будет хорошее решение. Любая помощь будет оценена.


person daltonb    schedule 28.07.2009    source источник


Ответы (3)


Извините, не думаю, что вы можете передавать аргументы своему сценарию 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
person Colin Macleod    schedule 28.07.2009
comment
Отлично, я не знала source. У меня команда VMD выполняется внутри цикла, и я подумал, что мне придется каждый раз переписывать весь сценарий Tcl; это намного лучше. Жаль, что нет возможности напрямую передавать аргументы. - person daltonb; 28.07.2009

Вы отправляете vmd содержимое файла program.tcl, а не результат выполнения программы. Если я вас понял, вы хотите подключить программу Tcl к vmd с помощью пайпа:

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

Изменить:

Итак, если vmd читает код Tcl на stdin, вы все равно можете передавать параметры без использования временного файла:

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...';
person glenn jackman    schedule 28.07.2009
comment
В этом случае оболочка попытается выполнить program.tcl как команду оболочки. Если бы я подключил ./program.tcl arg1 arg2 к VMD, он отправил бы только выходные данные. - person daltonb; 28.07.2009

Вы можете передать аргументы непосредственно в VMD, выполнив что-то вроде

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

Не забудьте добавить оператор quit в конец program.tcl.

person Leo    schedule 13.12.2010