2016-06-24 2 views
2

Я пытаюсь реализовать механизм повтора при выполнении внешней программы с использованием TCL. У меня возникают некоторые проблемы при попытке подачи STDIN во внешнюю программу. Теперь я работаю с упрощенным примером, пытаясь решить проблему. Возьмем следующий питон скрипт (simple.py):TCL - питание STDIN для exec

x = raw_input() 
y = raw_input() 
print x + y 

Входы 2 строки с выхода будет конкатенация результат строк.

Теперь следующая команда работает от интерпретатора TCL:

% exec python stuff.py << 1\n2 
12 

Однако, когда я пытаюсь разделить его на отдельные команды, или добавить их в строку, прежде чем делать это, не удается.

Сбой 1:

% set cmd "python simple.py << 1\n2" 
% exec $cmd 
couldn't execute "python simple.py << 1 
2": no such file or directory 

Сбой 2:

% set cmd1 "python simple.py" 
% set cmd2 "1\n2" 
% exec $cmd1 << $cmd2 

не смог выполнить "питон simple.py": нет такого файла или каталога

Сбой 3:

% set fullCommandString "exec python simple.py << 1\n2" 
% eval $fullCommandString 
Traceback (most recent call last): 
    File "simple.py", line 2, in <module> 
    y = raw_input() 
EOFError: EOF when reading a line 

Третий случай кажется который запускает скрипт, но он интерпретирует обе строки STDIN как одну.

Любая помощь приветствуется.

ответ

2

Команды Tcl не переинтерпретируют пробелы в своих аргументах по умолчанию. exec является одним из них, и он следует тем же правилам. Это означает, что вам нужно сказать Tcl, чтобы интерпретировать этот список слов как список слов, так как иначе это просто строка. К счастью, для этого есть {*}; расширение оператор синтаксис интерпретирует остальную часть слова как список Tcl и использует слова из этого списка в том месте, где вы его пишете. Это очень полезно найти.

Самый простой, чтобы исправить это на самом деле ваш второй случай:

% set cmd1 "python simple.py" 
% set cmd2 "1\n2" 
% exec {*}$cmd1 << $cmd2 

Вы можете исправить первую и третью, добавив список Tcl процитировать для обеспечения 1\n2 еще интерпретируется как одно слово (как в противном случае символ новой строки является вполне разумный разделитель элементов списка).

% set cmd "python simple.py << {1\n2}" 
% exec $cmd 
% set fullCommandString "exec python simple.py << {1\n2}" 
% eval $fullCommandString 

Третий можно записать более экономно, хотя:

% set fullCommandString "exec python simple.py << {1\n2}" 
% {*}$fullCommandString 

Как правило, если вы видите eval в современном Tcl (примечание: неnamespace eval или interp eval или uplevel), то это обычно указывает на то, что некоторый код может быть более эффективным и иметь меньше ошибок, переключаясь на использование exp осторожно.


Т.Л., д-р: Поместите {*} перед тем $cmd1 в вашем втором примере, чтобы получить идиоматическое исправить.