2016-01-07 2 views
2

У меня есть программа на C++, из которой я хочу выполнить несколько команд в оболочке. Мое текущее решение использовать функцию системы() и выглядит следующим образом:C++ выполнить много команд в оболочке

return_value = system(SETUP_ENVIRONMENT; RUN_USEFUL_APP_1); 
... do_something_else ... 
return_value = system(SETUP_ENVIRONMENT; RUN_USEFUL_APP_2); 
... do_something_else ... 
return_value = system(SETUP_ENVIRONMENT; RUN_USEFUL_APP_3); 
... 

Он работает, но SETUP_ENVIRONMENT занимает несколько секунд, что делает программу очень медленно. Но я должен запускать его каждый раз, так как system() запускается в новой оболочке каждый раз. Я хочу, чтобы иметь возможность настроить мою оболочку один раз, а затем запустить все команды в нем.

execute_in_shell(SETUP_ENVIRONMENT); 
return_value = execute_in_shell(RUN_USEFUL_APP_1); 
... do_something_else ... 
return_value = execute_in_shell(RUN_USEFUL_APP_2); 
... do_something_else ... 
return_value = execute_in_shell(RUN_USEFUL_APP_3); 
... 

Как это сделать?

Я нахожусь в Linux.

+1

Вы можете открыть оболочку в трубе и отправить команды через нее. –

+1

http://stackoverflow.com/questions/245600/using-a-single-system-call-to-execute-multiple-commands-in-c – mstruebing

+1

@mstruebing: Это предполагает, что вы знаете, какие программы запускать, когда и с каким аргументом. Труба - лучшее решение. – MSalters

ответ

0

У вас есть три разумных варианта для этого, в зависимости от вашей конкретной потребности.

Если различные вызовы, которые вы делаете для внешних инструментов, являются частью когерентной процедуры, вы можете - и, вероятно, должны - следовать советам @ dmi и написать короткий сценарий оболочки, который вы можете вызвать из своей программы на C++.

Если вам нужно начать процедуру здесь и там, вам может быть интересно запустить shell как уступчивый процесс и приложить вашу программу к нему - чтобы вместо того, чтобы разговаривать с вашим терминалом, вашей программы на C++.

Этот метод не очень сложно, но есть несколько подводных камней (например, некоторые программы, такие как SSH,SUDO или докер может ожидать быть присоединен к TTY). Он очень хорошо освещен в большинстве представлений о системном программировании (смотрите inter process communication и подпроцессы) для любого варианта Unix. Позвольте мне изложить эту процедуру:

  1. использовать систему труб вызов для создания труб (stdin_r, stdin_w)
  2. использовать систему труб вызов для создания труб (stdout_r, stdout_w)
  3. использовать систему труб вызов создавать трубы (stderr_r, stderr_w)
  4. использовать системные вилы вызов, чтобы дублировать программу
  5. в детстве вы закрываете stdin_w, stdout_r, stderr_r и использовать EXEC системного вызова параметризуется stdin_r, stdout_w, stderr_w к запустите оболочку.
  6. В родительском блоке вы закрываете stdin_r, stdout_w, stderr_w, и вы можете теперь писать команды в stdin_w и читать команду с stdout_r и stderr_r.

(Это намеренно очень схематично, я включил схему только для того, чтобы вы были уверены, что нашли нужное место в своем любимом учебнике).

Существуют сторонние библиотеки, реализующие все эти низкоуровневые материалы для вас.Вы можете использовать boost::process (который пока не является официальной частью повышения), использование которого проиллюстрировано на full tutorial. Есть plenty of alternatives, например pstreams.

Третий вариант заключается в том, чтобы избежать использования оболочки и выполнения непосредственно команд оболочки, которые вы используете. Это подход, за которым следует Rashell, библиотека OCaml, определяющая примитивы, позволяющие надежно составлять подпроцессы, которые вы можете использовать для своего собственного вдохновения.

1

Альтернативно, чтобы ответить 1, вы также можете использовать свою программу для создания сценария оболочки, который будет запускать все ваши полезные программы и выполнять этот скрипт сразу. Тогда оболочка не будет запускаться каждый раз для каждой конкретной полезной программы.

+1

Я не уверен, что такое среда настройки, но, как я понял, большая часть времени потребляется именно ею, верно? Возможно, тогда вы могли бы установить требуемую среду для своего основного процесса, а затем все порожденные процессы наследуют ее автоматически, так что вам не нужно настраивать ее для каждой конкретной полезной программы? или подумать над каким-либо другим способом совместного использования среды с ними, если это возможно (то есть через файл или разделяемую память) – dmi

Смежные вопросы