linux: закрыть или перенаправить стандартный вывод в /dev/null после отсоединения от терминала

У нас есть код Linux, который отсоединяется от терминала на основе реализации, найденной на https://web.archive.org/web/20180223192524/http://www.itp.uzh.ch/~dpotter/howto./daemonize.

Вот фрагмент кода из него:

....
freopen( "/dev/null", "r", stdin);
freopen( "/dev/null", "w", stdout);
freopen( "/dev/null", "w", stderr);

kill( parent, SIGUSR1 );
}

Вместо перенаправления на /dev/null я могу просто закрыть стандартные файловые дескрипторы следующим образом и добиться того же результата:

close(STDIN_FILENO);     
close(STDOUT_FILENO); 
close(STDERR_FILENO);

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


person drus    schedule 21.10.2015    source источник


Ответы (1)


Вы можете сделать и то, и другое, но перенаправление на /dev/null безопаснее и проще.

Если вы решите закрыться, вы должны убедиться, что любые внешние программы или библиотеки, которые вы вызываете, по-прежнему работают при закрытии stdin/stdout/stderr. Библиотеки и фреймворки различаются тем, как они справляются с этим:

  • Сценарии оболочки могут прерываться или вести себя неправильно, так как echo неожиданно возвращает неудачу.
  • Программы Python увидят, что произвольный оператор печати завершается ошибкой с исключениями, когда базовый буфер записывается.
  • Руби просто проигнорирует это.

Даже если вызываемые вами программы или библиотеки обычно ничего не печатают, вы не знаете, какие условные журналы они выполняют и как они там обрабатывают сбои.

Если известно, что весь код, который вы запускаете, не обрабатывает стандартный ввод-вывод, лучше просто перенаправить.

person that other guy    schedule 21.10.2015