Одно абсолютное правило - нельзя использовать косую черту /
или нулевой байт в имени файла. Косая черта - это разделитель каталогов, и его нельзя избежать. Нулевые байты указывают на конец имени и также не могут быть экранированы. Кроме того, в Linux разрешен любой символ (кроме случаев доступа к медиа или сетевым ресурсам, совместно используемым с другими файловыми системами), но некоторое количество символов может вызвать проблемы. Я думаю, что все современные * BSD также допускают любые символы, кроме /
и нулевых байтов, но у некоторых старых юниксов было больше ограничений.
Если вы хотите, чтобы имя файла работало в общей оболочке без кавычек, вам нужно избегать ! "# $ & '() *; ? [\] ^` {|} ~
и пробел (пробел, табуляция, новая строка). ~
нормально, если он находится в конце. В частности, в bash, ^
нормально, #
и ~
можно использовать везде, кроме начала, а =
можно использовать, за исключением имени команды (потому что это будет интерпретироваться как присвоение).
Помимо этого, вот несколько советов по переносу имени файла , в приблизительном порядке важности.
-
(тире / дефис). Команды могут интерпретировать это как параметр. ] ~
(тильда), потому что во многих приложениях это означает «домашний каталог». | foo
, что означает «прокрутка программы foo
», А не« записывать в файл | foo
», и аналогично с foo |
для вывода). \ /?: * ">
\ *? []
, потому что они подстановочные знаки . Кроме того, некоторые приложения, которые могут работать с несколькими файлами одновременно, интерпретируют эти символы как подстановочные знаки. txt
в myfile.txt
; иногда есть несколько расширений, например myfile.txt.gz
для сжатого ( .gz
) текстового ( .txt
) файла. .
скрыты по умолчанию в выводе команды ls
и во многих файловых браузерах. myfile
не связан с Myfile
. Традиционно имена файлов пишутся в нижнем регистре, в основном потому, что это упрощает их ввод. Раньше системы обычно сортировали прописные буквы перед строчными, поэтому существует традиция начинать имя файла с заглавной буквы, чтобы оно было первым в списках каталогов, но современные системы часто сортируют имена без учета регистра. Использование строчных букв позволяет избежать путаницы и легче набирать текст. Если вы не хотите запоминать все эти сложные случаи, вот только два простых правила:
a
- z
и цифр ] 0
- 9
, плюс -
для разделения слов и .extension
в конце имени файла. Например: my-file.txt
-
для разделения слов и .extension
в конце имени файла. Например: Jörgs Datei.txt
Последний совет: используйте формат ГГГГММДД (год-месяц-день, с 4 цифрами года и ведущим нулем в номере месяца и дня) для дат, например 20150622-report.txt
. Таким образом, сортировка имени файла дает вам хронологический порядок.
Одним из основных нововведений daemontools в середине 1990-х годов была идея надежного логирования . Демон-супервизор управлял двумя демонами, главным демоном и логарифмическим демоном. Он открыл канал перед вызовом любого из них, передав конец канала для записи в качестве стандартного вывода основного процесса демона, а конец канала для чтения в качестве стандартного ввода log процесса демона.. Он также сам хранил дескрипторы файлов открытыми на обоих концах канала. Таким образом, если демон журнала умер или был остановлен, а затем перезапущен, данные журнала, записанные в канал, будут сохранены и доступны для чтения и регистрации только что перезапущенным экземпляром демона журнала, потому что канал не будет закрыт.
Разработчики systemd не извлекли уроков из этого проекта.
systemd
организует порожденные сервисные процессы, если они настроены, чтобы их стандартные выходные данные отправлялись через сокет в процесс журнала. Но вместо того, чтобы, как в случае с daemontools, открывать канал и организовывать для каждого процесса наследование соответствующего конца канала, systemd
использует потоковый сокет AF_LOCAL
по адресу /run/systemd/journal/stdout
. Основные процессы подключаются как клиенты; процесс журнала слушает как сервер.
Это означает, что соединение данных имеет семантику клиентского -серверного сокета, а не унаследованную семантику канала. Если сервер умирает, соединение обрывается. Все буферизованные данные журнала теряются, а все дальнейшие данные, записанные основным демоном, отправляются в закрытый сокет и теряются. (Отчасти поэтому systemd имеет настройку IgnoreSIGPIPE
, которая по умолчанию имеет значение true. Запись вывода журнала в закрытый сокет также приводит к тому, что ядро пытается убить демона, записывающего журнал.)
Таким образом, если вы завершите процесс systemd-journald
, процесс выхода закроет соединения сокетов со всеми демоническими процессами, выходные данные которых он регистрирует, и весь дальнейший их вывод будет потерян.Невозможно исправить это и повторно подключить выходные данные основного процесса к процессу журнала. Необходимо перезапустить все основные процессы, чтобы systemd
re -открыло новое клиентское соединение с (недавно созданным )сервером журналов.
В 2016 году разработчики systemd решили обойти эту проблему. Это включало добавление процессам возможности передавать произвольные дескрипторы открытых файлов по своему выбору в процесс #1 и извлекать их позже. systemd-journald
делает это, когда сервер -завершает соединения с клиентами, которые он регистрирует, так что они остаются открытыми после перезапуска самого демона регистрации.
Проблема с этим механизмом заключается в том, что требуется гораздо больше работы, чтобы сделать его безопасным, а люди из systemd не имеют хорошего послужного списка, когда дело доходит до разработки безопасных вещей, как показали события только в этом году. Требуется гораздо больше работы, потому что кто может передать что и сколько открытых файловых дескрипторов в процесс #1 и как долго должен контролироваться и ограничиваться доступ. В противном случае существует множество возможных эксплойтов. (В дизайне daemontools сам процесс диспетчера служб открывает файловые дескрипторы, поэтому он имеет полный контроль над тем, какие файловые дескрипторы он оставляет открытыми для дочерних процессов. Его нельзя обмануть, злоупотребить или залить.)
В s6 Лорана Берко s6-svscan
делает обычную вещь daemontools с каналом между main и log сервисами. Он также имеет механизм для сохранения открытыми произвольных файловых дескрипторов. Это не делается кодом, работающим с привилегиями суперпользователя внутри диспетчера служб в процессе #1, как в systemd. Это делается совершенно непривилегированным процессом, который запускается отдельно от диспетчера служб.
s6-fdholderd
. с6. skarnet.org.