Сценарий оболочки Linux, чтобы узнать, имеет ли каталог (или файл) разрешение 777

#linux #shell

Вопрос:

Мы даем самое высокое разрешение на файл или каталог, используя эту команду:

 sudo chmod -R 777 directory
 

Теперь я хочу знать, выполнена ли эта команда уже для данного каталога.

Я знаю, что могу использовать -r для чтения, -w для записи и -x для выполнения в [ test ] блоках.

Но я хочу знать две вещи:

  • Это тоже каталог?
  • Есть ли у него эти разрешения для всех?

Как я могу получить эту информацию?

Обновить

Основываясь на комментарии @Barmar’а, я придумал это. Но это не работает:

 if [ stat /Temp | grep -oP "(?<=Access: ()[^)]*" == '' ]; then
    echo '/Temp folder has full access'
else 
    sudo chmod -R 777 /Temp
fi
 

Однако эта команда работает:

 stat /Temp | grep -oP "(?<=Access: ()[^)]*"
# prints => 0777/drwxrwxrwx
 

Как мне исправить синтаксическую ошибку в моем if-else заявлении?

Комментарии:

1. Используйте stat команду, она может возвращать много информации о файле/каталоге.

2. @ХоссейнФаллах : Я не знаю , чего вы хотите достичь с помощью своего if : он запускает команду [ , а не stat , и вы должны получить сообщение об ошибке об отсутствии ] . Что имело бы смысл , так это сделать что-то подобное if [[ $(stat ....) == '' ]] , но анализ выходных ls -ld /Temp данных, возможно, был бы проще. В то время как в общем случае, анализируя stdout ls обескуражен, я не вижу, что могло бы говорить против этого в вашем случае.

Ответ №1:

Вам не нужно обрабатывать вывод stat с grep помощью ; вы можете запросить stat только ту конкретную информацию, которую хотите. Смотрите справочную страницу, посвященную этой --format опции. Мы можем, например, написать:

 # ask stat for the file type and mode, and put those values into $1
# and $2
set -- $(stat --format '%F %a' /Temp)

if [[ $1 == directory ]]; then
  if [[ $2 == 777 ]]; then
    echo "/Temp folder has full access"
  else
    sudo chmod -R 777 /Temp
  fi
else
  echo "ERROR: /Temp is not a directory!" >amp;2
fi
 

Ответ №2:

Простой пример:

 #!/bin/bash

function setfullperm(){
    [ -d $1 ] amp;amp; 
    (
        [ "$(stat --format '%a' $1)" == "777" ] amp;amp; 
            echo "Full permissions are applied." || 
            ( echo "Setting full permissions" amp;amp; sudo chmod -R 777 $1 )
    ) || 
    ( echo "$1 is not a directory !" amp;amp; mkdir $1 amp;amp; setfullperm $1 )
}

export setfullperm
 

Источник сценария:

 $ source example.sh
 

Установите полные разрешения (777) для любого каталога, он сначала проверяет, существует ли каталог, если нет, он создаст его и установит разрешения.

Он экспортирует функцию setfullperm в оболочку, чтобы вы могли ее запустить:

 >$ setfullperm ali
ali is not a directory !
mkdir: created directory 'ali'
Setting full permissions

>$ setfullperm ali
Full permissions are applied.
 

Ответ №3:

Если вы используете (но не другие оболочки), вы можете сделать это с помощью простого шаблона глобуса zsh :

 setopt extended_glob null_glob
if [[ -n /Temp(#q/f777) ]]; then
    echo '/Temp folder has full access'
else
    sudo chmod -R 777 /Temp
fi
 

Шаблон /Temp(#q/f777) с null_glob extended_glob установленными параметрами и расширится до пустой строки, если /Temp это что-либо, кроме каталога с точными восьмеричными разрешениями 0777 (и /Temp если критерии выполнены). Для получения более подробной информации см. Квалификаторы глобусов в руководстве zsh.

Комментарии:

1. Однако я бы разделил каталог is-a и провел тесты с необходимыми разрешениями, чтобы лучше сообщать об ошибках. Что делать, если /Temp это существующий обычный файл?

Ответ №4:

Я не рекомендую использовать для этого статистику. Несмотря на широкое распространение, stat не является POSIX, что означает, что нет никакой гарантии, что ваш скрипт будет работать в будущем или работать на других платформах. Если вы пишете сценарии для производственной среды, я бы настоятельно рекомендовал вам рассмотреть другой подход.

Вам лучше использовать опцию ls(1) s-l и передать файл в качестве аргумента. Оттуда вы можете использовать опцию вырезать(1) s-c, чтобы захватить флаги режима файла.

Получить тип файла:

 ls -l <file> | cut -c1
 

Кроме того, не забывайте об операторе test-d, который проверяет, является ли файл каталогом.

Получить разрешения владельца:

 ls -l <file> | cut -c2-4
 

и так далее.

Этот подход совместим с POSIX и позволяет избежать недостатков использования статистики.

Комментарии:

1. Следует использовать «/bin/ls», чтобы избежать сглаживания.

2. @Рафаэль : Должно быть ls -ld , так как ОП сказал, что у него /Temp есть каталог.