Если я создаю файл как непривилегированный пользователь и изменяю режим разрешений на него 400
, он корректно воспринимается этим пользователем как доступный только для чтения:
$ touch somefile
$ chmod 400 somefile
$ [ -w somefile ] && echo rw || echo ro
ro
Все хорошо.
Но потом приходит root:
# [ -w somefile ] && echo rw || echo ro
rw
Какого черта? Конечно, root может писать в файлы, доступные только для чтения, но это не должно вызывать у него привычки: передовой опыт будет склонен диктовать, что я должен иметь возможность проверять бит разрешения на запись, а если нет, то он был установлен таким образом, по причине.
Думаю, я хочу понять, почему это происходит, и как я могу получить ложный код возврата при тестировании файла, для которого не установлен бит записи?
permissions
test
readonly
Богатый
источник
источник
4.1.2(1)-release
) и RHEL7 (4.2.46(2)-release
)./etc/dhcp/dhcpd.conf
, которым владеет root. Я использую поставляемую поставщикомdhcpd
. Полная катастрофа, а? Файл проверен в RCS, я автоматизирую использованиеrcsdiff
,ci
иco
потому что у нас есть операторы, которые должны ... работать. Проверка бита разрешения (-w
как подробно описаноtest(1)
) должна была стать первой строкой сбоя, работающей на основе, котораяci -u
оставляет файл доступным только для чтения. Я бросаю это и иду прямо кrcsdiff -q
проверке$?
. Невероятноdhcpd
? Это будет в собственностиdhcpd
.bash
иtest
привело меня к мысли, что это то, что[ -w
для.Ответы:
test -w
ака[ -w
не проверяет режим файла. Это проверяет, если это доступно для записи. Для root это так.Я бы проверил способ побитового сравнения с выводом
stat(1)
(«%a
Права доступа в восьмеричном виде»).Обратите внимание, что для подоболочки
$(...)
необходим0
префикс, так что выводstat
интерпретируется как восьмеричный(( ... ))
.источник
(( ... & ... ))
. Исправлена одна опечатка :-)if
необходимости, восьмеричные выходные данные разрешений%a
не являются%d
, и(( ... ))
нуждаются в префиксе,0
чтобы интерпретировать выходные данныеstat
как восьмеричные.man stat
говорит: «% d номер устройства в десятичном виде», но нам нужны «права доступа», нет? Ваша точка зрения о необходимости префикса 0 хорошо сделана, но я думаю, что мы просто должны ее там ввести :).stat -c 0%a
...Я думаю, что вы неправильно поняли, что
-w
делает. Он не проверяет, есть ли у файла «Права на запись», он проверяет, доступен ли файл для записи вызывающему пользователю.Точнее, звонки
access(2)
или аналогичные.например, если скрипт имеет,
if [ -w /etc/shadow ]
то если вы запуститеstrace
скрипт, вы можете увидеть строку, аналогичнуюТак как
root
может записать в файл, то он возвращает 0.например, как обычный пользователь:
Как корень
Это, несмотря на то, что
/etc/shadow
имеет разрешение000
на мою машину.Теперь то, что вы хотите сделать, становится интересным и не так просто.
Если вы хотите проверить простые разрешения, то проверьте
ls
вывод, или позвонитеstat
или подобное. Но поймите, что списки ACL могут переопределить эти разрешения. То, что файл 400 является разрешением, не мешает его записи ...источник
-w
:test(1)
явно: «ФАЙЛ существует и разрешение на запись предоставлено», а не « файл может быть записан текущим пользователем ». Ничего о переопределении разрешений, ни ACL.bash(1)
is cagey: "Истина, если файл существует и доступен для записи ."ksh(1)
делает тонкий намек на махинации: «-w file // True, если файл существует и доступен для записи текущим процессом .»zsh(1)
Относится кtest(1)
,zshmisc(1)
сформулирован какksh(1)
, иzshexpn(1)
подробно описывает некоторые интересные глобализации на основе разрешений.csh(1)
смешно кратко: «Доступ для записи».Пользователь root может делать все, что ему угодно, «нормальные» права доступа к файлам не имеют ограничений. Он не будет напрямую выполнять простой файл без каких-либо разрешений eXecute, просто для того, чтобы немного застраховаться от практических целей.
источник