При добавлении строки в конец файла текст иногда не записывается на новую строку

Обычный способ решить эту проблему в любой системе Unix, даже без ACL, состоит в том, чтобы создать новую группу, сделать user1и user2членами этой группы и настроить групповые разрешения для /data/web/tmpсоответственно(r-x).

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

(Для управления разрешениями в стиле Unix -важно понимать «группу» как «один набор правил разрешений», а не как «одну группу пользователей в соответствии с иерархией компании/учреждения» ).

Есть ли какая-либо причина, по которой вам необходимо использовать списки управления доступом, и вы не можете использовать этот стандартный подход?

2
13.01.2021, 17:35
1 ответ

Это связано с тем, что в исходном файле не было новой строки в конце последней строки. echo "182.2.3.4 host_1"не добавляет единицу в начале (, но добавляет единицу в конце, после ...host_1), поэтому в результирующем файле ее нет.

Из-за подобных проблем, а также потому, что, строго говоря, стандарт требует, чтобы "строка" заканчивалась символом новой строки , вы всегда должны иметь ее там. Некоторые утилиты могут давать неожиданное поведение без последней новой строки (, например. wc -lсчитает символы новой строки, поэтому такая строка не будет считаться строкой; а встроенная функция readвозвращает ложный статус, если не видит символ новой строки ). Некоторые редакторы всегда добавляют его, некоторые нет. В тех, которые этого не делают, не забудьте нажать Enter после последней строки или посмотреть, можете ли вы переместить курсор на «пустую строку» под ней, чтобы убедиться, что новая строка есть.

Подобные файлы можно исправить, например, с помощью.

perl -i  -pe '$_.= "\n" unless /\n$/' file-maybe-without-nl.txt

, который должен оставить завершающую новую строку как -, если она уже есть.(awk 1 < file.txt > fixed.txtтакже работает, но в awk нет стандартной функции редактирования места -. sedесть, но я не могу сказать, как это сделать с ним.)

Конечно, вы также можете безоговорочно добавить новую строку с чем-то вроде echo >> /etc/hostsили echo -e '\n182.2.3.4 host_1' >> /etc/hosts,но это добавило бы ложные пустые строки в середине, если файл был правильно отформатирован перед добавлением.

Способ проверки последней строки новой строки без необходимости чтения всей строки состоит в том, чтобы использовать tail -n1или tail -c1для получения последней строки (или фрагмента строки )или только последнего символа. Тогда

[ "$(tail -c1 "$f")" = "" ] || echo >> "$f"

можно использовать, чтобы добавить его, если это необходимо. (Это основано на подстановке команды, которая поглощает все новые строки, поэтому ее расширение пусто, если есть новая строка . )Или использовать read(, который возвращает ложный статус, если не видит новую строку):

tail -c1 file | read -r tmp || echo >> file

(Идея tailи всей последней команды заимствована из сообщения в блоге здесь:https://backreference.org/2010/05/23/sanitizing-files-with-no-trailing-newline/)

Обратите внимание, что символ возврата каретки (CR )отличается от символа новой строки/строки -перехода (LF ), который используется в качестве разделителя строки в Unix -подобных системах. (CR+LF используется для обозначения конца строки в DOS и Windows.)

15
18.03.2021, 22:36

Теги

Похожие вопросы