Я намагався викликати команду chmod у неправильному порядку. chmod file.txt -r
Це спрацювало чомусь. chmod file.txt +r
З іншого боку, відмовився працювати. Чому це? З якої причини одна команда працює, а інша ні?
Я намагався викликати команду chmod у неправильному порядку. chmod file.txt -r
Це спрацювало чомусь. chmod file.txt +r
З іншого боку, відмовився працювати. Чому це? З якої причини одна команда працює, а інша ні?
Відповіді:
Це вигадка щодо того, як GNU chmod обробляє введення, і не є переносним для всіх POSIX-сумісних реалізацій chmod.
Зауважте, що синтаксис команд-рядків POSIX chmod
вимагає, щоб режим був першим, як і GNUchmod
(параметри повинні надходити і до режиму). Все інше - це бездокументована химерність реалізації.
Тепер, чому це відбувається саме в цій реалізації:
Це вказується в посібнику :
Однак, як правило, "
chmod a-w file
" є кращим іchmod -w file
(без цього--
) скаржиться, якщо він поводиться інакше, ніж "chmod a-w file
".
Коротко, параметри, що розбираються, getopt
мають префікс "a" -
. Як і в ls -a
, a
це варіант. Довга форма ls --all
має all
як варіант. rm -rf
(еквівалентно rm -r -f
) має r
і f
варіанти, і варіанти.
Все інше - це необов'язковий аргумент, який технічно називають операндами . Мені подобається називати ці позиційні аргументи, оскільки їх значення визначається їх відносним становищем. У chmod
, перший позиційний аргумент - це режим, а другий позиційний аргумент - це ім'я файлу.
Оптимально режим не повинен вести з a -
. Якщо це так, вам слід використовувати --
для примусового розбору як операнда замість опції (тобто використання chmod a-w file
або chmod -- -w file
замість chmod -w file
. Це також пропонує POSIX.
Якщо ви подивитеся на вихідний код , ви помітите, що він використовує getopt для аналізу параметрів командного рядка. Тут є спеціальна обробка для "неправильних" режимів, таких як -w
:
case 'r':
case 'w':
case 'x':
case 'X':
case 's':
case 't':
case 'u':
case 'g':
case 'o':
case 'a':
case ',':
case '+':
case '=':
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
/* Support nonportable uses like "chmod -w", but diagnose
surprises due to umask confusion. Even though "--", "--r",
etc., are valid modes, there is no "case '-'" here since
getopt_long reserves leading "--" for long options. */
Беручи свій приклад:
chmod a-r file.txt
було б найбільш надійним викликом.chmod +r file.txt
працює, тому що перший аргумент позиційно трактується як режим.chmod -r file.txt
все ще працює, тому що -r
інтерпретується як короткий r
варіант і має спеціальний варіант.chmod -- -r file.txt
є правильним і працює, тому що -r
позиційно інтерпретується як режим. Це відрізняється від випадку без, --
тому що при --
цьому -r
не інтерпретується як варіант .chmod file.txt -r
все ще працює, тому що -r
інтерпретується як короткий r
варіант і має спеціальний варіант. Параметри не залежать від позиції. Це технічно зловживає недокументованою вигадкою.chmod file.txt +r
не працює, тому що +r
є операндом, а не варіантом. Перший операнд ( file.txt
) інтерпретується як режим ... і не вдається проаналізувати.getopt
команда , а не звичайна бібліотека в розділі 3 . По-друге, це посилання на optstring
, тобто список прийнятих параметрів (у chmod
джерелі optstring
встановлено "Rcfvr::w::x::X::s::t::u::g::o::a::,::+::=::"
). Зв'язаний розділ "РЕЖИМ сканування" не має нічого спільного з масивом аргументів argv
який містить аргументи, передані в програму.
a+rwx
і ви робите щось на зразокchmod * +r
, і цейa+rwx
файл стане першим у глобальному розширенні.