2014-12-03 5 views
2

У меня есть программа, которая должна запускать программу, которую мы будем называть externalProg параллельно в нашем linux (CentOS) кластере - или, скорее, ей нужно запустить много экземпляров externalProg, каждый на разных сердечники. Каждая «нить» создает 3 файла на основе нескольких параметров - входные данные для externalProg, командный файл, который сообщает externalProg, как выполнить мой файл, и скрипт bash для настройки среды (вызывает сценарий настройки, предоставленный производителем) и на самом деле вызовите externalProg с моими входами.C++ выполнить temp-файл как bash-скрипт

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

mkstemp("PREFIX_XXXXXX") 

для этих входных файлов. После запуска внешней программы я извлекаю соответствующие данные и сохраняю их и закрываю временные файлы (поэтому удаляя их).

Мы будем называть файлы, созданные (которые на самом деле имеют имя на основе вышеприведенного шаблона)

tmpInputs - Inputs to externalProg 
tmpCommand - Input that tells externalProg how to execute tmpInputs 
tmpBash - bash script to set up and call externalProg with my inputs 

Файл tmpBash выглядит что-то вроде

source /path/to/setup/script # Sets up environment variables 
externalProg < /path/to/tmpCommand 

где tmpCommand является только простой текст файл.

Проблема, с которой я столкнулась, - это выполнение скрипта bash. В рамках моей программы я звоню

ostringstream launchcmd; 
launchcmd << "bash " << path_to_tmpBash 
system(launchcmd.str().c_str()); 

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

Как ни странно, если я вернусь к терминалу и типа

bash /path/to/tmpBash 

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

После нескольких экспериментов я определил, что system() вызывает/bin/sh в нашем кластере. Если изменить launchcmd выглядеть

/path/to/tmpBash 

(Так что полная команда должна выглядеть как/bin/ш/путь/к/tmpBash), я получаю сообщение о запрете доступа, что не удивительно. Проблема в том, что я не могу chmod + x tmpBash-файл, пока он все еще открыт, и если я закрою файл, он будет удален, поэтому я не уверен, как это решить.

Есть ли что-то явно неправильное, что я делаю, или система() имеет какой-то нюанс, который мне не хватает?

редактировать: Я хотел бы добавить, что я могу успешно называть вещи как

system("echo $PATH") 

и получить ожидаемые результаты (в данном случае, мой по умолчанию $ PATH).

+0

'ofstream launchcmd;' Вы имели в виду ['ostringstream launchcmd;'] (http://en.cppreference.com/w/cpp/io/basic_ostringstream)? (Просто потому, что вы заявляете, что хотите использовать 'system (launchcmd.str(). C_str());') –

+0

Я действительно имел в виду ostringstream! Я отредактировал мой вопрос, чтобы исправить это. – kjfergu

ответ

1

Две отдельные идеи:

  • Измените переменную SHELL среды, чтобы быть /bin/bash, а затем вызвать system(),

или:

  • Используйте execve directly `execve ('/ bin/bash ', ['/path/to/tmpBash '], environment)
+0

Я проверил, и $ SHELL уже/bin/bash. Я работаю над попыткой execve или execv, но у меня все еще такая же проблема, как и раньше, странно. – kjfergu

+0

@ user3741834: Можете ли вы дать мне какой-нибудь функциональный пример кода для игры? Я был бы рад исправить это с начальной точки, но я не хочу писать это с нуля. –

+0

Одна секунда здесь. Я не могу напрямую вставить свой код (проблема с безопасностью), но я работаю над примером, который воссоздает проблему. – kjfergu

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