don_crissti, спасибо! Это меня очень близко подобрало. Это сработало, если файл начинался с:
group = groupY
owner = ownerX
Но он пропустил, если владелец был первым: owner = ownerX group = groupY
Используя ваше решение и найдя онлайн-руководство по awk, я изменил его, чтобы охватить оба случая. Хотя я изначально этого не запрашивал, меня интересуют только настройки режима. Поэтому вместо печати всех строк в диапазоне я печатаю только строки, содержащие режим. Проблема решена:
awk '/group =/{t=0}
/group = groupY/{t=1}
/owner =/{p=0}
{if ((t==1) && (p==1) && (seperator_printed==0)) {
print "-------------------------"
seperator_printed=1
}
}
{if ((t==1) && (p==1)) {
if ($0 ~ /mode/) {print NR, $0}
} else {
separator_printed=0
}
}' infile
У вас есть (в основном )исчерпывающий список системных вызовов здесь .
Вы заметите, что нет вызова «заменить содержимое этого индексного дескриптора». Изменение этого контента всегда подразумевает:
Шаг 4 можно выполнить раньше. Также есть несколько сокращений, таких как pwrite , которые напрямую записывают по указанному смещению, объединяя шаги #2 и #3, или запись вразброс .
Альтернативным способом является использование сопоставления памяти , но это еще хуже, поскольку каждый записанный байт может быть отправлен в базовый файл независимо (концептуально, как если бы каждая запись была 1 -байтом. write
звоните ).
→ Суть в том, что лучший сценарий, который у вас может быть, это по-прежнему 2 операции :одна write
и одна truncate
.
В каком бы порядке вы их ни выполняли, вы все равно рискуете, что другой процесс запутается с промежуточным файлом и в итоге получите поврежденный файл.
Как вы заметили, именно поэтому канонический подход заключается в создании нового файла, вы знаете, что являетесь единственным автором (вы даже можете гарантировать это, комбинируя O_TMPFILE
и linkat
), а затем атомарно перенаправляя старое имя в новый файл.
Есть еще два варианта, однако оба они в чем-то не работают:
Он позволяет запретить доступ к файлу другим процессам, установив специальную комбинацию флагов. Звучит как инструмент для работы, верно? Однако:
Warning: the Linux implementation of mandatory locking is unreliable.
Since Linux 4.5, mandatory locking has been made an optional feature. This is an initial step toward removing this feature completely.
Это вполне логично, поскольку Unix всегда избегала блокировок. Они подвержены ошибкам, и невозможно охватить все крайние случаи и гарантировать отсутствие взаимоблокировок.
Устанавливается с помощью системного вызова fcntl . Однако он носит только рекомендательный характер, и большинство программ его просто игнорируют.
На самом деле это годится только для управления блокировками общего файла между несколькими взаимодействующими процессами.
Is there some way to do it atomically like rename(2) but preserve hard links?
№
Индексные дескрипторы являются низкоуровневыми, почти деталями реализации. Очень немногие API признают свое существование (. Я считаю, что stat
семейство вызовов единственное ).
Все, что вы пытаетесь сделать, скорее всего, зависит либо от неправильного использования структуры файловых систем Unix, либо от того, что вы просто требуете от нее слишком многого.
Может ли это быть чем-то вроде XY -проблемы ?