LINUX.ORG.RU

вопрос по скрипту, запускаемому внешней программой


0

1

Здравствуйте. Я должен пояснить, что я новичек в линукс (и вообще ламер по жизни). Но обычно мне хватает google чтобы находить ответы на нужные вопросы. Тут вопрос такой, что по ключевым словам гуглится совсем не то, что мне надо. Задача такова, что имеется типичное (классическое) консольное приложение. Даже два. Одно - консольное, но с графическим окном OpenGL, запускаемым паралелльно консоли. Приложение специфическое, вряд ли стоит даже уточнять. Запускается из терминала <имя_приложения> <ключ> <путь к файлу> И тут я решил сделать себе хорошо, как я про это думаю. Поставил я Лазарус Фри Паскаль и накидал простую программку,такую что цепляешь файл из интерфейса, нажимаешь кнопку, и вот оно- запускается. Ну просто сложно мне привыкнуть, все время прописывать путь к файлу, cd и все такое. Все бы ничего, но приложение запускается без терминала. То есть - то, которое с окном - только одно окно запускается. А то, которое без окна - где то в памяти запускается, но выдачи в терминал нет. Пробовал написать sh файл с командами на запуск, тот же самый результат. Все прекрасно, но консоли нет. Система ubuntu 64 bit, xfce Вопрос такой: как прописать sh файл, чтобы запускался терминал и в него уже подавались команды. И вопрос второй, не менее важный - как сделать чтобы данный код работал во всех линуксах (потому что я программы привык шарить для всех, и чтобы меня не ругали заочно - хочется сделать именно универсальный код). Как вариант, думал написать какой нибудь терминал на Лазарусе. Но тяму на это нет. В общем, спасибо, если кто что то посоветует. Гуглпоиск провалился потому что на запрос типа sh ... terminal выпадают более общие темы.

Вопрос такой: как прописать sh файл, чтобы запускался терминал и в него уже подавались команды.

Многие эмуляторы терминалов умеют запускаться сразу с какой-нибудь командой. Например, для xfce4-terminal:

xfce4-terminal --command='tail -f /var/log/Xorg.0.log'
То же самое для xterm:
xterm -e 'tail -f /var/log/Xorg.0.log'
В общем, смотри что есть в хелпе и документации.

И вопрос второй, не менее важный - как сделать чтобы данный код работал во всех линуксах (потому что я программы привык шарить для всех, и чтобы меня не ругали заочно - хочется сделать именно универсальный код).

Тебе придётся разобраться как сделать это с разными эмуляторами терминала (думаю, что это умеют все юзабельные). Ну и предусмотреть в своей программе какую-нибудь настройку, чтобы пользователи выбирали тип терминала или могли указать свою команду для запуска.

Deleted ()
Последнее исправление: Deleted (всего исправлений: 1)

Вы сначала изучите это приложение. Может ему не нужен терминал, может оно просто пишет в stdin и stdout, не анализируя, терминал ли это. То есть попробуйте запустить его с перенаправлением вывода в файл и посмотреть, что туда пишется.

Если приложению не нужен терминал, то думаю, что будет достаточно просто читать в вашей программе вывод этого приложения и выводить его в текстовое окно. И это будет самым универсальным решением, так как в общем случае в системе вобще может не быть программы эмулятора терминала.

mky ★★★★★ ()

Спасибо! xfce4-terminal работает, принцип понял xterm не стоит, ну и ладно. stdout попробовал передать в Memo - через pipes получилось, но частично. То есть заставку пишет, а в процессе работы (как происходит в случае терминала) - не пишет. Сложно сказать почему, скорее я что то недоделал, но все равно очень рад!

leonsiy ()
Ответ на: комментарий от leonsiy

То есть заставку пишет, а в процессе работы (как происходит в случае терминала) - не пишет.

Скорее всего пишет в stderr.

ABW ★★★★★ ()
Ответ на: комментарий от leonsiy

То есть заставку пишет, а в процессе работы (как происходит в случае терминала) - не пишет. Сложно сказать почему

просто остальное оно пишет в stderr

такую что цепляешь файл из интерфейса, нажимаешь кнопку, и вот оно- запускается. Ну просто сложно мне привыкнуть, все время прописывать путь к файлу, cd и все такое

разумнее настроить любимый файловый менеджер добавив пункт «открыть в..» для подходящих файлов (по расширениям или media-type)

MKuznetsov ★★★★★ ()
Ответ на: комментарий от MKuznetsov

А можно одно и то же расширение настроить на разные действия? дело в том, что там есть ключи для запуска в разных режимах, и настроить командно можно какой то один, как я думаю

leonsiy ()

В нотификации выхлоп выводить - не вариант? Я накидал скриптик.

Вообще, для универсальности нужно дёргать алиас на выбранный по умолчанию терминал (x-terminal-emulator вроде, точно не помню). Но со скармливанием параметров могут быть проблемы.

MiniRoboDancer ★☆ ()
Ответ на: комментарий от leonsiy

Нет, но можно настроить на запуск обёртки, запрашивающей нужный вариант, так что удобство и трудоёмкость приблизительно те же, что и в твоём решении.

ABW ★★★★★ ()

Есть ещё один вариант - без терминала, вывод обрабатывать прямо в программке на твоей форме, запустив другой процесс через пайп. ХЗ, как его на паскале делать, только на C/C++ этим занимался.

peregrine ★★★★★ ()

Вопрос такой: как прописать sh файл, чтобы запускался терминал и в него уже подавались команды. И вопрос второй, не менее важный - как сделать чтобы данный код работал во всех линуксах

1. читай ман к своему терминалу. Это все могут

2. никак.

emulek ()

В общем спасибо всем. Самый первый ответ представляется мне наиболее пользительным с точки зрения простоты. Второй самый верный с идейной точки зрения и в общих чертах тоже работает (но почти). С точки зрения UnixWay надо решать маленькую задачу, но решать ее хорошо, поэтому я подумаю что лучше

Внизу процедура считывания вывода в Memo в реальном времени (Lazarus Free Pascal)

procedure TForm1.RunApp(commandstringline:string) ;

const
  C_BUFSIZE = 2048;
var
  Hbk: TProcess;
  Buffer: pointer;
  SStream: TStringStream;
  nread: longint;
begin
  Hbk := TProcess.Create(nil);

  // Replace the line below with your own command string
  Hbk.CommandLine := commandstringline;
  //

  Hbk.Options := [poUsePipes, poStderrToOutPut];
  Hbk.Execute;

  // Prepare for capturing output
  Getmem(Buffer, C_BUFSIZE);
  SStream := TStringStream.Create('');

  // Start capturing output
  while Hbk.Running do
  begin
    nread := Hbk.Output.Read(Buffer^, C_BUFSIZE);
    if nread = 0 then
      sleep(3000)
    else
      begin
        // Translate raw input to a string
        SStream.size := 0;
        SStream.Write(Buffer^, nread);
        // And add the raw stringdata to the memo
        Memo1.Lines.Text := Memo1.Lines.Text + SStream.DataString;
// Added this--
  Application.ProcessMessages;
  Form1.Memo1.SelStart := Length(Form1.Memo1.Lines.Text);
//
      end;
  end;

  // Capture remainder of the output
  repeat
    nread := Hbk.Output.Read(Buffer^, C_BUFSIZE);
    if nread > 0 then
    begin
      SStream.size := 0;
      SStream.Write(Buffer^, nread);
      Memo1.Lines.Text := Memo1.Lines.Text + SStream.Datastring;

    end
  until nread = 0;





  // Clean up
  Hbk.Free;
  Freemem(buffer);
  SStream.Free;
end;  
 	
leonsiy ()

В общем спасибо. Первый вариант наверно самый простой Второй тоже в принципе работает - и вот код внизу для считывания вывода в Memo в режиме реального времени для Lazarus Free Pascal Есть некоторые небольшие проблемы с работой второго кода, и поскольку Unix Way предполагает замечательное правило «решай конкретную задачу, но решай ее хорошо» я подумаю еще что выбрать в качестве окончательного варианта. Но это уже вопросы немного в стороне от топика


procedure TForm1.RunApp(commandstringline:string) ;

const
  C_BUFSIZE = 2048;
var
  Hbk: TProcess;
  Buffer: pointer;
  SStream: TStringStream;
  nread: longint;
begin
  Hbk := TProcess.Create(nil);

  // Replace the line below with your own command string
  Hbk.CommandLine := commandstringline;
  //

  Hbk.Options := [poUsePipes, poStderrToOutPut];
  Hbk.Execute;

  // Prepare for capturing output
  Getmem(Buffer, C_BUFSIZE);
  SStream := TStringStream.Create('');

  // Start capturing output
  while Hbk.Running do
  begin
    nread := Hbk.Output.Read(Buffer^, C_BUFSIZE);
    if nread = 0 then
      sleep(3000)
    else
      begin
        // Translate raw input to a string
        SStream.size := 0;
        SStream.Write(Buffer^, nread);
        // And add the raw stringdata to the memo
        Memo1.Lines.Text := Memo1.Lines.Text + SStream.DataString;
// Added this--
  Application.ProcessMessages;
  Form1.Memo1.SelStart := Length(Form1.Memo1.Lines.Text);
//
      end;
  end;

  // Capture remainder of the output
  repeat
    nread := Hbk.Output.Read(Buffer^, C_BUFSIZE);
    if nread > 0 then
    begin
      SStream.size := 0;
      SStream.Write(Buffer^, nread);
      Memo1.Lines.Text := Memo1.Lines.Text + SStream.Datastring;

    end
  until nread = 0;





  // Clean up
  Hbk.Free;
  Freemem(buffer);
  SStream.Free;
end;  

leonsiy ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.