Я намагався викликати команду 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файл стане першим у глобальному розширенні.