chmod: отсутствует операнд после a t

#linux #bash #shell

#linux #bash #оболочка

Вопрос:

Пытаюсь исправить доступные для записи файлы и получаю сообщение об ошибке ниже:

 chmod: missing operand after a t
  

вот мой код

 df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type d -perm -0002 -a ! -perm -1000 2>/dev/null | xargs chmod a t
  

Есть мысли?

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

1. Если бы вы использовали -exec вместо xargs , у вас не было бы этой проблемы (или нескольких других).

2. Если у вас GNU xargs , вы можете использовать опцию --no-run-if-empty (aka -r ), чтобы избежать выполнения команды один раз, даже если нет аргументов (поведение, требуемое POSIX, вероятно, из уважения к историческому прецеденту, а не потому, что это казалось действительно хорошей идеей). Но вам лучше избегать использования xargs .

3. @JonathanLeffler Все еще вызывает команду, когда нет аргументов, почему, это похоже … все еще расширяется до нерасширенного шаблона глобуса, когда он ничему не соответствует, и передает бесполезный аргумент.

4. @Kaz, … есть чертовски веская причина nullglob , по умолчанию отключена: широко доступные программы командной строки имеют поведение по умолчанию, которое они используют, когда не передают аргументы; передача им глобального литерала означает, что вместо возврата к этому поведению по умолчанию у них есть возможность выдать ошибку. Поведение GNU xargs по умолчанию, напротив, — это то, на что у меня нет защиты.

Ответ №1:

Здесь вообще нет необходимости xargs — это источник ваших ошибок, и он мог бы стать источником еще большего количества ошибок, если бы у вас было содержимое, смонтированное в каталоге с пробелами или кавычками (или буквенными обратными косыми чертами) в его имени.

 {
  read _                           # consume header
  while IFS= read -r dirname; do   # ...iterate over later lines...
    find "$dirname" -xdev -type d 
      '(' -perm -0002 -a ! -perm -1000 ')' 
      -exec chmod a t '{}'   2>/dev/null
  done
} < <(df --output=target --local)  # tell df to emit only the one column you want
  

Чтобы пояснить, почему xargs является источником ошибок в этом коде:

  • GNU xargs (но не BSD xargs) вызовет команду без каких-либо аргументов, если ее входные данные не содержат содержимого. Это ваша непосредственная проблема.
  • Все реализации xargs, совместимые с POSIX, будут анализировать кавычки и обратную косую черту (используя их) и разделять ввод на пробелы, если только расширения не используются для указания ему поступать иначе (например, -0 [тем самым требуя ввода с разделителями NUL] или, в версии GNU, -d $'n' [для корректной работы с разделителями новой строки]). Это означает, что если бы у вас был контент, смонтированный в /media/Movie Name With Spaces , xargs пытался бы работать find с /media/Movie , Name , With , и Spaces отдельно; /media/Movie Name With Spaces "And Quotes" сделал бы то же самое, но с And Quotes (без пробелов!) в виде одного слова.

Более того, здесь нет никакой выгоды от использования xargs , если ваш find код использует современные (2006 года) Расширения POSIX: -exec somecommand {} передает столько аргументов somecommand , сколько поместится при каждом вызове, точно так же, как xargs somecommand и делает.

Ответ №2:

Это происходит, когда вы не предоставляете аргументов для chmod :

 $ chmod a x
chmod: missing operand after ‘a x’
Try 'chmod --help' for more information.
  

Таким образом, предположительно, команда:

 df --local -P | awk {'if (NR!=1) print $6'} | 
        xargs -I '{}' find '{}' -xdev -type d -perm -0002 -a ! -perm -1000 2>/dev/null
  

не генерирует никаких выходных данных, т.Е. У вас нет ни одного каталога с соответствующими требуемыми perm ограничениями в заданных каталогах для поиска. Запустите только эту команду, без chmod , чтобы убедиться в этом.