Системная команда выполняется, но немедленно блокируется

Я пытаюсь использовать модуль TProcess для выполнения ssh, чтобы подключиться к одному из моих серверов и предоставить мне оболочку. Это переписывание того, что было у меня в Ruby, поскольку время выполнения для Ruby очень медленное. Когда я запускаю свою функцию Process.Execute, мне предоставляется оболочка, но она сразу же становится фоновой. Запуск pgrep ssh показывает, что он работает, но у меня нет к нему никакого доступа, использование fg не возвращает его. Для этого сегмента код выглядит следующим образом:

  if HasOption('c', 'connect') then begin
    TempFile:= GetRecord(GetOptionValue('c', 'connect'));
    AProcess:= TProcess.Create(nil);
    AProcess.Executable:= '/usr/bin/ssh';
    AProcess.Parameters.Add('-p');
    AProcess.Parameters.Add(TempFile.Port);
    AProcess.Parameters.Add('-ntt');
    AProcess.Parameters.Add(TempFile.Username + '@' + TempFile.Address);
    AProcess.Options:= [];
    AProcess.ShowWindow:= swoShow;
    AProcess.InheritHandles:= False;
    AProcess.Execute;
    AProcess.Free;
    Terminate;
    Exit;
  end;

TempFile — это переменная типа TProfile, представляющая собой запись, содержащую информацию о сервере. Система каталогизации и поиска работает нормально, но подтягивание оболочки не работает.


person Mark    schedule 03.09.2015    source источник
comment
тебе еще нужен ответ?   -  person Jorge Aldo    schedule 19.09.2015


Ответы (1)


...
AProcess.ShowWindow:= swoShow;
AProcess.InheritHandles:= False;
AProcess.Execute;
AProcess.Free;
...

Вы запускаете процесс, но не ждете его завершения. Это из документации по Execute:

Execute фактически выполняет программу, указанную в CommandLine, применяя столько указанных параметров, сколько поддерживается на текущей платформе.

Если в Options указана опция poWaitOnExit, то вызов вернется только после завершения выполнения программы (или в случае возникновения ошибки). Если этот параметр не задан, вызов возвращается немедленно[sic], но вызов WaitOnExit можно использовать для ожидания его закрытия или вызов Running можно использовать для проверки того, выполняется ли он еще. .

Вы должны установить опцию poWaitOnExit в опциях перед вызовом Execute, чтобы Execute блокировался до тех пор, пока процесс не завершится. Или же вызовите AProcess.WaitOnExit, чтобы явно дождаться завершения процесса.

person Kenster    schedule 03.09.2015
comment
Установка любого из них приводит к тому, что мой ввод будет скрыт, а все последующие строки вывода на пульте будут добавлять три символа табуляции в начале строки. Мне очень трудно понять, почему, есть идеи? - person Mark; 03.09.2015
comment
Если у вас есть новый вопрос, вы должны задать новый вопрос. И включите весь соответствующий исходный код в его текущей форме. - person Kenster; 03.09.2015
comment
Правильный вариант — poUsePipes, чтобы позволить процессу общаться с родителем через потоки, которые предоставляет tprocess. вы должны установить буфер канала соответственно через pipebuffersize. вы должны использовать выполнить, а не ждатьфорексит. вы работаете асинхронно, а не синхронно. по сути, этот ответ неверен, и я напишу свой позже. - person Jorge Aldo; 19.09.2015