2016-09-15 9 views
0

Я использую следующий фрагмент кода для создания tar.gz -archive в обширном программном обеспечении для измерения. После сбора некоторых данных в нескольких файлах я хочу архивировать и сжимать их для последующего использования. Все работает нормально, когда я запускаю программу из оболочки, все данные собираются и архивируются правильно.Создание tar.gz-архива из C++-программы не работает

Однако программа должна запускаться автоматически после запуска системы встроенной системы Linux. Когда он запускается через скрипт в /etc/init.d, файлы данных не архивируются/сжимаются, хотя я получаю возвращаемое значение 0. Кроме того, tar.gz-файл создается, но он пуст. Все остальное работает нормально.

Может ли кто-нибудь объяснить, что я должен сделать в этом специальном случае автоматического запуска?

int returnValue = -1; 
std::string jobString = RESULT_PATH; 
jobString += "/"; 
jobString += lastJobString; 
std::string jobFiles = lastJobString + "*.*"; 

std::string cmd = "tar cvf - "; 
cmd += jobFiles; 
cmd += " | gzip > "; 
cmd += jobString; 
cmd += ".tar.gz"; 

std::cout << "archiving and compressing " << jobFiles << ": " << cmd << std::flush << std::endl; 

returnValue = system(cmd.c_str()); 

std::cout << "archiving and compressing finished. Code: " << returnValue << std::flush << std::endl; 

Я знаю, что есть несколько librariers, как libarchive, libtar и т.д., которые использовать не ленивый, как стреляя системную команду, но я хотел бы знать, почему это не работает для моего случая.

Кроме того, версия tar в моем загруженном ящике не поддерживает опцию z.

+2

Иногда при запуске программ из скриптов устанавливаются не все пути, поэтому вам нужно использовать полный путь, например '/ bin/tar'. Ваш файл '.tar.gz' всегда будет создан при использовании' '' оператора, который создает пустой файл при ошибке. Вы также можете перенаправить stderr в файл журнала, чтобы увидеть сообщение об ошибке. Вы также можете просто использовать «tar czf archive.tar.gz filenames» без ручного вызова gzip и перенаправления stdout в файл. –

+0

@ Karsten Koop благодарит за ваш ответ. Как я уже упоминал, у меня нет ошибки в качестве возвращаемого значения из вызова. Кроме того, версия «tar'in my busy box не имеет опции« z ». – bushmills

+0

Возврат 0 не означает, что команда действительно выполняется. Даже система («blabla 123 | gzip> out») вернет 0, как я только что попробовал. – Ming

ответ

-1

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

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

std::string cmd = "sh -c \" cd "; 
cmd += SOURCE_DIR; 
cmd+= " && tar cvf - "; 
cmd += jobFiles; 
cmd += " | gzip > "; 
cmd += jobString; 
cmd += ".tar.gz"; 

returnValue = system(cmd.c_str()); 

Возможно, это поможет другим пользователям перейти к той же же проблеме.

+0

Большинство программ «tar» (и, конечно, [GNU tar] (https://www.gnu.org/software/tar/) ...) принимают параметр «-C» для изменения каталога. И вы можете называть [chdir (2)] (http://man7.org/linux/man-pages/man2/chdir.2.html) в своей программе на C++. –

+0

@Basile спасибо за этот намек. – bushmills

+1

Ваша системная команда является хрупкой и небезопасной: что, если какой-то вредоносный пользователь установит 'sourceDir' в' rm -rf $ HOME'? Остерегайтесь [инъекции кода] (https://en.wikipedia.org/wiki/Code_injection) !! –