Являются ли связанные команды атомарными?

Что касается добавленного вопроса отображения как процент (на основе ответа jasonwryan):

awk '/^Mem/ {printf("%u%%", 100*$3/$2);}' <(free -m)

получите процент путем дайвинга 3-го поля 2-м и печатью как целое число (не окружение!).

Править: добавленный двойной '%' в printf (первый выходит из буквенного символа, предназначенного для печати).

8
08.09.2015, 18:36
4 ответа

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

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

12
27.01.2020, 20:08

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

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

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

 sudo rm somefile 
sudo touch somefile 
 

вы можете рассмотреть это:

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

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


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

3
27.01.2020, 20:08

Нет, но

sudo rm somefile; sudo touch somefile

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

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

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

 exec 3>somefile

Тогда другой процесс может разъединить (= удалить) какой-то файл, и файловый дескриптор, в котором какой-то файл был открыт первым процессом (в данном случае 3), продолжит ссылаться на исходное содержимое somefile, который теперь находится в подвешенном состоянии.

sudo touch somefile

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

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

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

2
27.01.2020, 20:08

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

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

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

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

6
27.01.2020, 20:08

Теги

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