Почему мы заключаем в двойные кавычки оценку знака доллара в Bash? [дубликат]

Предоставьте разрешения на выполнение/поиск (x) для «других» в каталоге lighthttpd.

$ chmod o+X lighthttpd

Селектор битов файлового режима X в chmod включает выполнение/поиск только в том случае, если файл является каталогом (или уже имеет разрешение на выполнение для какого-либо пользователя).

Бит выполнения/поиска, установленный для каталогов, позволяет пострадавшему пользователю войти (вызов open()) в каталог и получить доступ к файлам и каталогам внутри. Кроме того, им нужны права на чтение (r) для самих файлов (которые, согласно вопросу, уже установлены).

Без разрешения на чтение (r) в каталоге пользователи не могут получить содержимое каталога, поэтому им необходимо знать имя файла, в котором они находятся. собирается получить доступ заранее.

Если базовая файловая система поддерживает списки контроля доступа Posix , вы также можете предоставить разрешение на выполнение/поиск в каталоге с помощью setfacl для конкретного пользователя без настройки владельца или групповое назначение:

$ setfacl -m u:user:x lighthttpd

Вы можете определить, поддерживают ли файловые системы Posix ACL, проверив, были ли они смонтированы с параметром монтирования acl / запустив mount :

$ mount | grep /dev/sdaX
/dev/sdaX on /mountpoint type ext4 (rw,acl)

If acl отсутствует в выводе mount, возможно, это один из параметров по умолчанию для этого типа файловой системы.Вы можете проверить это с помощью tune2fs :

$ sudo tune2fs -l /dev/sdaX |grep acl
Default mount options:    user_xattr acl 

Если acl не включен, вы по какой-то причине не хотите предоставлять всем пользователям возможность входа в каталог, вы можете следовать Совет Ларкейта и свяжите файл, который вы хотите, чтобы пользователи могли получить доступ к другому пути в файловой системе.

0
24.02.2017, 00:59
2 ответа

Не все ваши три примера в точности одинаковы.

В последних двух:

if [ "${a}" == 0 ]; then
ffmpeg -framerate 2 -pattern_type glob -i "*.png" -pix_fmt yuv420p output.mp4

Если $ a не был заключен в кавычки, а его значение содержало символы $ IFS (по умолчанию пробел, табуляция и новая строка) или символы подстановки. , это может привести к тому, что [ получит более трех аргументов (кроме [ и ] ]), что приведет к ошибке; {{ 1}} аналогично, если бы значение $ a было пустой строкой, это привело бы к тому, что [ получил слишком мало аргументов:

$ (a=0; [ $a == 0 ] && echo OK)
OK

(но только если $ IFS в настоящее время не содержит 0 )

$ (a='foo bar'; [ $a == 0 ] && echo OK)
bash: [: too many arguments

(со значением по умолчанию $ IFS )

$ (a=; [ $a == 0 ] && echo OK)
bash: [: ==: unary operator expected

(даже с пустым $ IFS или с zsh (который в противном случае не реализует этот неявный оператор split + glob при расширениях без кавычек))

$ (a='*'; [ $a == 0 ] && echo OK)
bash: [: too many arguments

(при запуске в каталоге, содержащем как минимум 2 не скрытых файла ).

При цитировании ошибки нет:

$ (a='foo bar'; [ "$a" == 0 ] && echo OK)
$ (a=; [ "$a" == 0 ] && echo OK)

Ваш первый пример отличается. Правила раскрытия в двойных кавычках являются особыми, когда речь идет о массивах; если a обозначает массив , то:

  • $ a - первый элемент массива (строго говоря, это $ {a [0]} ], даже если элемент с индексом 0 не определен);

  • $ {a [*]} или $ {a [@]} - это элементы массива, дополнительно разделенные по $ IFS (пробел, табуляция, новая строка по умолчанию);

  • "$ {a [@]}" - это элементы массива, не разделенные на $ IFS .

Итак, ваш цикл для i в "$ {index [@]}"; do ... фактически не работает , в зависимости от содержимого массива. Например:

$ (declare -a a=(a b c); printf '%s\n' $a)
a

$ (declare -a a=(a b c); printf '%s\n' ${a[*]})
a
b
c

$ (declare -a a=(a 'b c'); printf '%s\n' ${a[*]})
a
b
c

$ (declare -a a=(a 'b c'); printf '%s\n' ${a[@]})
a
b
c

$ (declare -a a=(a 'b c'); printf '%s\n' "${a[*]}")
a b c

$ (declare -a a=(a 'b c'); printf '%s\n' "${a[@]}")
a
b c
5
28.01.2020, 02:15

Короче говоря, это сделано для избегайте расширений, сделанных специальными символами, которые могут быть внутри переменной, например ! . Двойные кавычки также называются «слабыми кавычками», поскольку некоторые символы будут интерпретироваться (знак доллара, обратные кавычки и обратная косая черта). Одиночные кавычки - это «сильные кавычки», и ничего не будет интерпретироваться.

Цитата документация bash :

3.1.2.3 Двойные кавычки

Заключение символов в двойные кавычки ( ") сохраняет буквальное значение всех символов. в кавычках, за исключением $ , обратная кавычка , \ , и, если включено раскрытие истории, ! . Когда оболочка находится в режиме POSIX (см. Bash POSIX Mode), ! не имеет особого значения в двойных кавычках, даже если включено раскрытие истории. ..

Примеры слабого и сильного цитирования:

  • echo "Ваш ПУТЬ: $ PATH" - напечатает Ваш ПУТЬ:
  • echo 'Ваш ПУТЬ: $ PATH' - Будет напечатано Ваш ПУТЬ: $ PATH

Отвечая на ваш вопрос, мы используем двойные кавычки с переменными, чтобы разрешить $ быть расширенным, но во избежание дальнейшего увеличения содержимого переменной расширен.

Связанные материалы:

2
28.01.2020, 02:15

Теги

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