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

373

Существует команда chmod для установки прав доступа к файлам, но можно ли получить права доступа к файлам в восьмеричном режиме (например, 755) из командной строки?

Анвар
источник
2
Для таких людей, как я, которые случайно оказались на этой странице, но на самом деле искали, как это сделать на Mac: stackoverflow.com/a/14855227/470749
Райан,
2
stat --format "%A" $FILEдает вам удобочитаемый drwxr-x---формат. что может или не может быть полезным.
Тревор Бойд Смит

Ответы:

535

Ты можешь попробовать

stat -c "%a %n" *

Замените *на соответствующий каталог или точное имя файла, которое вы хотите проверить.

Со страницы руководства stat ,

-c  --format=FORMAT
          use  the  specified  FORMAT instead of the default; output a newline after
          each use of FORMAT
%a     Access rights in octal
%n     File name

Использование:

  • С файлами:

    $ stat -c "%a %n" ./Documents/Udev.html 
    664 ./Documents/Udev.html
    
  • С папками:

    $ stat -c "%a %n" ./Documents/
    755 ./Documents/
    

(Ссылка)

Джокердино
источник
57
на Mac OS, используйте stat -f '%A %a %N' *(кредит: geeklog.adamwilson.info/article/58/… )
s2t2
1
Если вам удобнее ls:for f in $(ls -a); do stat -c "%a %n" $f; done;
usandfriends
2
@usandfriends зацикливание на выходе ls- плохая идея. Если вы действительно хотите использовать цикл, вы можете сделатьfor f in *; do stat "%a %n" "$f"; done
Том Фенек
1
Почему в Mac OS все немного изменилось (даже в Unix iso Utils)? Есть ли реальная причина этого?
Василис
2
Пожалуйста, @hackel, расскажи нам, как ты на самом деле себя чувствуешь. лол!
MikeSchinkel
44

Права доступа к файлам в Linux могут отображаться в восьмеричном формате с помощью команды Linux stat.

Просто нажмите Ctrl+ Alt+ Tна клавиатуре, чтобы открыть терминал. Когда он откроется, перейдите в каталог, где вы хотите найти разрешения для файлов в восьмеричном режиме.

stat -c '%A %a %n' *

% A Права доступа в удобочитаемой форме

% a Права доступа в восьмеричном виде

% n Имя файла

Восьмеричные числа и разрешения

Вы можете использовать восьмеричное число для представления режима / разрешения:

r: 4
w: 2
x: 1

Например, для владельца файла вы можете использовать восьмеричный режим следующим образом. Разрешение на чтение, запись и выполнение (полное) для файла в восьмеричном виде: 0 + r + w + x = 0 + 4 + 2 + 1 = 7

Только чтение и запись для файла в восьмеричном виде: 0 + r + w + x = 0 + 4 + 2 + 0 = 6

Только разрешение на чтение и выполнение для файла в восьмеричном виде: 0 + r + w + x = 0 + 4 + 0 + 1 = 5

Используйте вышеуказанный метод для расчета разрешения для группы и других. Допустим, вы хотите дать полное разрешение владельцу, разрешение на чтение и выполнение для группы и разрешение только на чтение для других, а затем вам нужно рассчитать разрешение следующим образом: Пользователь = r + w + x = 0 + 4 + 2 + 1 = 7 группа = r + w + x = 0 + 4 + 2 + 0 = 6 другие = r + w + x = 0 + 0 + 0 + 1 = 1

Действующее разрешение 761.

Источник: http://kmaiti.blogspot.com/2011/09/umask-concept.html

Митч
источник
2
Начальные 0 также представляют особый бит: pastebin.com/6ymkFt71
Брайам,
36

Как подробно описано в «755» -Style разрешений с «LS» от Адама Courtemanche на AgileAdam.com , вы можете создать псевдоним lso , который действует как , ls -lно немного обрабатывает выход 1 с разрешениями дисплея также в восьмеричной системе . Это добавляет начальный столбец, показывающий трехзначные 2 восьмеричные разрешения. Как написано, это работает для большинства файлов и каталогов, но не работает должным образом, если установлены биты sticky или setuid / setgid . 3

alias lso="ls -alG | awk '{k=0;for(i=0;i<=8;i++)k+=((substr(\$1,i+2,1)~/[rwx]/)*2^(8-i));if(k)printf(\" %0o \",k);print}'"

Это серьезный недостаток, хотя, как techtonik указывает . Вы не можете передавать аргументы этому lsoпсевдониму так же, как и lsкоманде , потому что awkвместо них они принимаются как дополнительные аргументы . Таким образом, вы не можете запускать lsoопределенный файл или каталог, а также не можете передавать никакие параметры (например -F, или --color) lso.


Исправление заключается в том, чтобы определить lso как функцию, а не псевдоним.

lso() { ls -alG "$@" | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/)*2^(8-i));if(k)printf(" %0o ",k);print}'; }

Если вы пытаетесь сделать это интерактивно в своей оболочке, запустите, unalias lsoчтобы удалить псевдоним - вы можете сделать это либо до, либо после определения функции. Если вы помещаете его в файл с источником, например ~/.bashrc, просто выньте aliasстроку и добавьте определение функции.

Почему это работает? В отличие от псевдонимов, функции оболочки bash могут принимать позиционные параметры , то есть аргументы командной строки . "$@"расширяется до полного списка аргументов , в результате чего аргументы lsoфункции передаются ls. (В отличие от определения псевдонима, тело функции не заключено в кавычки; следовательно, необходимо было удалить \символы до $и ".)

Так как вы можете передать параметры , lsoкогда определена таким образом , как функции, вы можете удалить -aи -Gварианты из определения - вы можете передать их вручную в тех случаях , когда вы хотите их. ( Опция требуется для деталей , таких как права доступа к файлам , которые будут показаны на всех , так что нет никакой пользы для его удаления.)-l

lso() { ls -l "$@" | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/)*2^(8-i));if(k)printf(" %0o ",k);print}'; }

Спасибо techtonik за то, что он указал на ограничение в определении lsoпсевдонима, мотивируя меня расширить этот пост материалом о том, чтобы сделать его вместо этого функцией.


1 Можно заметить, что это нарушает общее правило о том, что неls нужно анализировать выходные данные из . lsпроизводит очень удобочитаемый вывод; это вводит идиосинкразии и ограничения, делающие его вообще непригодным в качестве ввода для других команд. В этом случае мы выполняем синтаксический анализ, lsпоскольку хотим сохранить точное поведение,ls кроме одного добавленного нами изменения.

2 Одно из ограничений этого псевдонима, которое также применяется к версии функции, показанной ниже, и которая может рассматриваться как ошибка, состоит в том, что он отображает только три восьмеричных цифры, даже когда четвертая восьмеричная цифра равна нулю. Как jfmercer уже справедливо указывал , что восьмеричные цифры , показанные здесь , не отражают липкий бит , если он присутствует, ни Setuid или setgid бит.

- Более серьезно , чем просто не показывает четвертую восьмеричную цифры является то , что этот метод предполагает , что они не установлены, и если они есть - если вы видите t, sили Sв строке разрешения - то вы должны игнорировать восьмеричные цифры . Это связано с тем, что биты выводятся из строки разрешений таким образом, что не учитываются липкие биты setuid / setgid.

Элия ​​Каган
источник
не работает с каталогами -awk: read error (Is a directory)
анатолий техтоник
@techtonik Спасибо за указание на это! Я (наконец) обновил этот ответ, чтобы включить исправление для этого.
Элия ​​Каган
1
Вы можете добавить --colorпараметр для отображения цветовlso() { ls -alG "$@" --color | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/)*2^(8-i));if(k)printf(" %0o ",k);print}'; }
tagplus5
1
Вы нашли решение проблемы с залипанием setuid / setgid с момента публикации этого сообщения?
Сильвестрис
21

Просто расширяем \ упрощаем предыдущие ответы, связанные с «stat»:

Вы можете просто запустить:

stat <path_to_file>

Вывод будет содержать восьмеричное разрешение вместе с другой информацией.



Подробности (версия и пример статистики):

# stat --version
stat (GNU coreutils) 8.4


[user@localhost ~]# touch /tmp/TEST_PERMISSONS

[user@localhost ~]# chmod 644 /tmp/TEST_PERMISSONS

[user@localhost ~]# stat /tmp/TEST_PERMISSONS
  File: `/tmp/TEST_PERMISSONS'
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: fd00h/64768d    Inode: 1010058     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2015-08-26 18:58:59.000000000 +0300
Modify: 2015-08-26 18:58:59.000000000 +0300
Change: 2015-08-26 18:59:16.000000000 +0300

Обратите внимание: ( 0644 / -rw-r - r--)

Вано
источник
6

Для переносимости вы можете использовать perl:

$ perl -e 'printf "%04o %s\n", (stat)[2] & 07777, $_ for @ARGV' *.txt
0644 1.txt
0644 2.txt
0644 3.txt
0644 4.txt
0600 PerlOneLiner.txt
0664 perl.txt

Если вы хотите заметить, когда происходит ошибка, попробуйте:

perl -e '
for (@ARGV) {
    print "$!: $_\n" and next unless -e;
    printf "%03o %s\n", (stat)[2] & 07777, $_;
}
' *.txt
cuonglm
источник
2
Помимо переносимости, решение @ cuonglm показывает четыре восьмеричных символа, а не три , тем самым показывая состояние «залипания», о котором часто забывают.
Jfmercer
2

Вы можете использовать findс -printfдействием.

lsне отображает восьмеричные разрешения, но вы можете использовать этот findобходной путь:

find path -printf "%m:%f\n"

Например, чтобы проверить мой каталог «Видео»:

$ find Videos -printf "%m:%f\n"
755:Videos

Спецификатор %mформата указывает -printfдействию печатать восьмеричные разрешения, тогда как %fспецификатор формата заставляет его печатать имя файла.

Вы можете передать несколько имен файлов find. Вы можете даже использовать шары (например, find * -printf "%m:%f\n").

Вам не нужно использовать тест, как -nameили -iname; достаточно указать имена файлов или каталогов, которые вас интересуют, в качестве отправных точек find. То есть, указывайте их имена в качестве аргументов сразу после слова find, как показано выше.

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

  • По умолчанию findрекурсивные подкаталоги аналогичны ls -R. Если вы не хотите findпосещать подкаталоги начальных точек, которые вы передаете ему, вы можете добавить -maxdepth 0(или использовать -maxdepthс другими значениями, чтобы указать, насколько глубоко вы хотите, чтобы это пошло).

    $ find Documents -maxdepth 0 -printf "%m:%f\n"
    755:Documents
    
  • %fотображает только имя файла, поэтому, если findтребуется выполнить возврат к файлу, вы можете не знать, где он находится. Чтобы показать путь, начиная с любой начальной точки, в которой был найден файл, используйте %pвместо этого.

    $ find /boot -printf "%m:%p\n"
    755:/boot
    644:/boot/initrd.img-4.4.0-92-generic
    600:/boot/System.map-4.4.0-93-generic
    600:/boot/vmlinuz-4.4.0-92-generic
    600:/boot/vmlinuz-4.4.0-93-generic
    ....

Смотрите man findдля получения дополнительной информации об использовании findкоманды.

Другой метод ( lsа awk)

Это может быть использовано для вывода списка всех файлов каталогов с их разрешениями:

ls -l | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/) \
             *2^(8-i));if(k)printf("%0o ",k);print}'

По сути, это та же команда, что и в псевдониме Адама Куртманчаlso , на который приведен этот ответ , она запускается как одна команда. Если вы используете это только один раз или в редких случаях, вы можете не захотеть писать его как псевдоним или функцию оболочки.

Maythux
источник