Я занимаюсь разработкой программы на C ++, которая может работать весь день. Он выводит на стандартный вывод, и я хочу сжать этот вывод. Несжатый вывод может быть много ГБ. Запускаемый сценарий оболочки Bourne компилирует код C ++ и запускает программу следующим образом:
./prog | gzip > output.gz
Когда я прерываю скрипт с помощью CTRL- C, файл .gz всегда поврежден. Когда я запускаю программу из терминала и прерываю ее, используя CTRL- C, файл .gz также всегда поврежден. Когда я запускаю программу терминала и завершаю его с помощью Linux killall, файл .gz в порядке.
С другой стороны, на терминале cat <large_file> | gzip > cat.gz
может быть прерван с помощью CTRL- C и На cat.gz всегда хорошо. Поэтому я подозреваю, что у cat есть какой-то обработчик сигналов, который я должен также реализовать в своей программе на C ++ ... но, глядя на онлайн-реализацию cat, я не нашел ничего подобного. Тем не менее, я реализовал это:
void SignalHandler(int aSignum)
{
exit(0);
}
void Signals()
{
signal(SIGINT, SignalHandler);
signal(SIGKILL, SignalHandler);
signal(SIGTERM, SignalHandler);
}
... и даже что-то в скрипте b sh, но ничего не помогает. После CTRL- C файл gz поврежден.
Вопросы:
- Что у кошки есть, чего нет у моей программы?
- Как мне прекратить работу? мой скрипт / программа, использующая CTRL- C с файлом zip по порядку?
Edit 1
Открытие результирующего файла с помощью zcat
дает некоторый вывод, но затем: gzip: file.gz: unexpected end of file
. Если открыть его в Менеджере архивов в Ubuntu, появится всплывающее сообщение: An error occurred while extracting files.
Edit 2
Пробная очистка; никаких изменений в проблеме не наблюдалось.
Изменить 3
Больше информации о проблеме: Подпись отсутствующего конца (EOCDR)
Fix archive (-F) - assume mostly intact archive
zip warning: bad archive - missing end signature
zip warning: (If downloaded, was binary mode used? If not, the
zip warning: archive may be scrambled and not recoverable)
zip warning: Can't use -F to fix (try -FF)
zip error: Zip file structure invalid (file.gz)
maot@HP-Pavilion-dv7:~/temp$ zip -FF file.gz --out file2.gz
Fix archive (-FF) - salvage what can
zip warning: Missing end (EOCDR) signature - either this archive
is not readable or the end is damaged
Is this a single-disk archive? (y/n): y
Assuming single-disk archive
Scanning for entries...
zip warning: zip file empty
maot@HP-Pavilion-dv7:~/temp$ ls -lh file2.gz
-rw------- 1 maot maot 22 feb 15 15:18 file2.gz
maot@HP-Pavilion-dv7:~/temp$
Изменить 4
Спасибо @ Максим Егорушкин, но это не работает. Прерывание сценария с помощью CTRL- C убивает prog
перед выполнением обработчика сигнала сценария. Следовательно, я не могу послать ему сигнал, он уже пропал ... и без вывода SignalHandler
. Когда prog
запускается из командной строки, выводится SignalHandler
. Прога:
#include <iostream>
#include <unistd.h>
#include <csignal>
void SignalHandler(int aSignum)
{
std::cout << "prog: Interrupt signal " << aSignum << " received.\n";
fflush(nullptr);
exit(0);
}
int main()
{
for (int sig = 1; sig <=31; sig++)
{
std::cout << " sig " << sig;
signal(sig, SignalHandler);
}
while (true)
{
std::cout << "prog: Sleep ";
fflush(nullptr);
usleep(1e4);
}
}
Скрипт:
#!/bin/sh
onerror()
{
echo "onerror(): Started."
ps -jef | grep prog
killall -s SIGINT prog
exit
}
g++ -Wall prog.cpp -o prog
trap onerror 2
prog | gzip > file.gz
Результат:
maot@HP-Pavilion-dv7:~/temp$ test.sh
^Conerror(): Started.
maot 16733 16721 16721 5781 0 16:17 pts/1 00:00:00 grep prog
prog: no process found
maot@HP-Pavilion-dv7:~/temp$
Редактирование 5 минимальных рабочих решений
Реализация ответа Максима Егорушкин. Скрипт:
#!/bin/sh
g++ -Wall prog.cpp -o prog
prog | setsid gzip > file.gz & wait
Прог:
#include <iostream>
#include <unistd.h>
#include <csignal>
void SignalHandler(int aSignum)
{
std::cout << "prog: Interrupt signal " << aSignum << " received.\n";
exit(0);
}
int main()
{
signal(SIGINT, SignalHandler);
while (true)
{
std::cout << "prog: Sleep ";
usleep(1e4);
}
}