Связаны ли цепи с атомами?

Если бы процесс постоянно записывался в файл, и я хотел взять под свой контроль файл с помощью root, я мог бы сделать что-то вроде этого:

sudo rm somefile; sudo touch somefile 

Возможно ли добавить процесс добавления к файлу между этими двумя командами? Если да, существует ли способ гарантировать, что никакая другая команда не будет запущена между ними?

4 Solutions collect form web for “Связаны ли цепи с атомами?”

Прикованная командная строка – это в основном небольшой скрипт оболочки; он выполнит первую команду, используя обычную процедуру fork + exec, дождитесь ее выхода, а затем запустит вторую так же. Между этими двумя командами существует некоторое количество времени, которое оболочка берет в своей бухгалтерии и обработке, во время которой происходит обычная многопроцессорная обработка, а произвольные другие процессы могут делать произвольные другие вещи. Поэтому ответ «нет». (Если вы действительно это сделаете, вы обнаружите, что запись в каталоге для somefile исчезает, но сам файл остается (поскольку он открыт процессом), пока он не будет закрыт. Дисковое пространство, используемое файлом, не будет восстановлено до тех пор, пока это не произойдет. Между тем, команда touch создаст новый, несвязанный файл с тем же именем и путем.)

Если вы хотите изменить права собственности на файл на root, просто выполните sudo chown root:root somefile (хотя я не уверен, как это повлияет на процессы с открытым файловым дескриптором). Если вы хотите уничтожить текущее содержимое файла, попробуйте truncate -s 0 somefile ( truncate -s 0 somefile процесс будет продолжать добавляться в пустой файл). Если это что-то еще, возможно, уточните, что вы хотите сделать.

Нет. Команда rm за которой следует команда touch не является атомарной. Между двумя командами будет длительное время – возможно, в миллисекундах. За это время многое может случиться. Если вам не повезло, ваши учетные данные sudo могут даже истечь.

Единая программа, вызывающая unlink и open вызовы, оставила бы гораздо более короткое окно для гонки, но это все равно могло случиться.

Более безопасный подход заключается в создании нового файла с временным именем и использовании системного вызова rename . «Перезаписать» имя с системным вызовом rename гарантированно будет атомарным. Это может быть достигнуто с помощью touch и mv .

Но процесс, который открыл старый файл для записи, может продолжать писать его долго после его удаления. Это будет иметь место как для файла, удаленного с помощью unlink и для удаления с помощью rename .

Когда процесс имеет открытую для чтения файловую дескриптор, не имеет значения, что вы делаете с правами собственности или разрешениями: процесс может продолжать доступ к файлу. Вы даже можете удалить файл, и процесс сможет продолжить доступ к нему с помощью дескриптора файла.

Рассмотрите разрешения как управляющие ворота для получения дескриптора файла.

Если вы хотите создать файл атомарно, вместо этого выполните следующее:

 sudo rm somefile sudo touch somefile 

вы можете подумать об этом:

 sudo touch anotherfile sudo perl -e "rename 'anotherfile', 'somefile'" 

который будет атомарно заменять somefile . (Я предпочел бы использовать mv -f но я не могу найти оператор, который гарантирует, что это вызовет системный вызов rename(2) .


Возможно, вы могли бы обновить свой вопрос, чтобы объяснить, что вы подразумеваете под «взять под контроль файл». У вас может возникнуть проблема XY .

Нет, но

sudo rm somefile; sudo touch somefile

безопасен в большинстве ситуаций.

Большинство процессов открывают файлы, а затем используют полученный файловый дескриптор для доступа к содержимому файла.

Если процесс открывает некоторый файл, в sh:

  exec 3>somefile 

Затем другой процесс может освободить (= удалить) некоторый файл, а файл filedescriptor, в котором некоторый файл был открыт первым процессом (в этом случае 3), будет продолжать ссылаться на исходное содержимое некоторого файла, который теперь является файлом в неопределенности.

 sudo touch somefile 

создаст новый, несвязанный somefile, и все процессы, у которых был старый файл somefile, и теперь используют только файл filedescriptor для ссылки на него, не будут затронуты, потому что они ссылаются на другой файл – тот, который теперь находится в подвешенном состоянии.

Если процесс без полномочий root ссылается на некоторый файл по имени, он получит ошибку EPERM, потому что новый файл somefile принадлежит root.

Если вы хотите предотвратить несколько процессов под одним и тем же пользователем (например, root) от развращения файла, linux имеет обязательную и консультативную блокировку файла. Вы можете использовать команду flock в сценариях оболочки для консольного блокирования файлов (подробнее см. Man-страницу).

  • Повторение общих строк в длинном пакетном скрипте
  • Места в Bash, где сопоставление образцов выполняется с помощью регулярных выражений?
  • Лучшие решения для этого: tail -200 / var / log / messages | головка -100
  • Использование опции -n с pushd и popd
  • Как переместить файлы в подкаталоги по счету?
  • Как использовать две переменные в одном цикле
  • Когда я могу использовать временную IFS для разделения поля?
  • назначение переменной из сценария bash
  • Сценарий bash работает только с отладчиком
  • Как я должен понимать «.» В расширении имени файла?
  • Bizzarre поведение «эхо !!» под интерактивным Bash. Это особенность?
  • Предупреждение mdoc: пустая строка ввода #xx
  • Interesting Posts

    Общий объект "libarchive.so.7" не найден, требуется "pkg"

    Перейти на один уровень от несуществующего пути

    Преобразовать в WAV, используя FFMPEG для трубы в LAME?

    Как запустить скрипт, когда SSSD создает домашний каталог для нового пользователя

    Есть ли что-то вроде вина для запуска приложений OSX на Linux?

    comm сбой при вводе переменной bash

    создайте новый столбец на основе существующих столбцов, используя оператор else в awk

    Использование find -exec как печатать имя файла перед каждой строкой?

    Нужно ли мне * `exit 0` в конце` rc.local`?

    Создание программного обеспечения для Linux, созданного с использованием многострочной

    Распределение Linux с удаленным рабочим столом?

    Использовать xargs для перемещения файлов из каталога

    Имена скопированных файлов с USB-устройства на жесткий диск все заглавные. Как это исправить?

    Проблема с устройством хранения: ошибки ввода-вывода, но нет поврежденных секторов?

    Как клиенты X знают, что им нужно будет подключиться к TCP-порту 6000+ <номер дисплея>?

    Linux и Unix - лучшая ОС в мире.