В сценарии оболочки, как я могу легко и неинвазивно проверить доступ на запись в файл без фактической попытки изменить файл?
Я мог бы проанализировать вывод stat
, но это кажется действительно сложным и, возможно, хрупким, хотя я не уверен, насколько статистический вывод отличается в разных реализациях и времени.
Я мог бы добавить в конец файла и посмотреть, если это удастся, но это потенциально опасно, по двум причинам, которые я могу думать:
- Теперь мне нужно удалить дополнение, и в случае, если какой-то другой процесс записывает в файл, это сразу становится нетривиальным, так как моя строка больше не является последней.
- Любой процесс, читающий файл, может иметь произвольные требования к содержимому этого файла, и я, возможно, просто нарушил это приложение.
источник
man test
илиman [
type -a
test
использований ,euidaccess
который просто проверяет биты разрешения . Нет ли других факторов (например, SELinux), которые могли бы запретить доступ на запись?&&
и||
имеют равный приоритет. Они оцениваются слева направо.Другой подход:
Это попытается открыть файл для добавления и, если это удастся, не выполнить команду (то есть выполнить нулевую команду ) с выводом в файл.
Помните, что это создает пустой файл, если он не существует.
-w
Операторtest
команды может просто сделать ,stat
а затем попытаться выяснить , выглядит ли это , как вы должны иметь доступ. Моя альтернатива (выше) более надежна, чемtest
подход в некоторых особых условиях, потому что она заставляет проверку доступа выполнять ядро, а не оболочка. Например,stat
может вернуть значение режима, которое вводит в заблуждение.источник
touch
найти файл, который принадлежал мне, но не имел права на запись, и это удалось. Я предполагаю, чтоchmod
это файл иchmod
вернул его. Так что,touch
похоже, абсолютно бесполезен в качестве ответа на вопрос.vim
имеет такое поведение, что позволяет быстро изменять права доступа при необходимости записи в файлы только для чтения. Я проверил сstrace
,touch
сopen
ошибкамиEACCES
, но последующий вызов кutimensat
успеху, поэтому я думаю, чтоtouch
в целом завершается успешно.utimensat(2)
говорит: « Требования к разрешениям: 1. Доступ на запись (или) 2. Эффективный идентификатор пользователя вызывающего абонента должен совпадать с владельцем файла…»>> file
не переносимо (например, запускает NULLCMD в zsh), используйтеtrue >> file
вместо этого. И если файл является именованным каналом, он имеет неприятные побочные эффекты.G-мужчина прав:
[ -w ]
не всегда говорит правду. Здесь, чтобы справиться с несуществующим файлом и сообщением об отказе в доступе из оболочки:Обновление : выглядит пугающе, не так ли? Ну, это так. Хм ... как это выразить ... НЕ ИСПОЛЬЗУЙТЕ ЭТО, если только вы точно не знаете, что находитесь в условиях, которые он требует для работы, как ожидается. Смотрите комментарий Стефана.
Что делать вывод тогда? Даже если
[ -w ]
не говорит правду, это единственная команда, которая предназначена для выполнения этой работы. Если этого не произойдет, мы обвиним в этом, напишем отчеты об ошибках, и это сработает в будущем. Лучше проверить условия, при которых он работает и использовать[ -w ]
; написать специальный код для особых случаев. Обходные пути имеют свои условия.лучший априори .
источник
test -w
в большинстве реализаций использованияaccess(2)
должно быть достаточно для проверки разрешений.