Что означает последнее «-» (дефис) в опциях «bash»?


15

В этом уроке нам нужно выполнить следующую команду:

# curl -sL https://rpm.nodesource.com/setup_6.x | sudo -E bash -

Что означает последний -(дефис) после bash?

Я видел много команд с этим, и не мог найти себе логическое объяснение и не нашел, как переформулировать поиск в Google. Это вывод команды piped?



2
Загрузка материалов из сети и передача их прямо в sudo bashзвуки действительно страшны. Попробуйте найти учебник, который не поощряет такие практики.
Хмакхольм покинул Монику

Это учебник по npm, но я согласен с вами ...
Омар БИСТАМИ

1
Если вам нужно искать вещи с символами в них, попробуйте symbolhound.com.
Джо

Ответы:


31

Bash ведет себя несколько нестандартно, когда дело доходит до -.

POSIX говорит:

Рекомендация 10.
Первый --аргумент, который не является аргументом-параметром, должен быть принят в качестве разделителя, указывающего конец параметров. Любые последующие аргументы должны рассматриваться как операнды, даже если они начинаются с -символа.

[...]

Рекомендация 13.
Для утилит, которые используют операнды для представления файлов, которые должны быть открыты для чтения или записи, -операнд должен использоваться для обозначения только стандартного ввода (или стандартного вывода, когда из контекста ясно, что файл вывода указывается) или файл с именем -.

И

Если требуется, чтобы утилита, описанная в томе «Shell and Utilities» POSIX.1-2017 как соответствующая этим рекомендациям, принимала или не принимала операнд, -обозначающий стандартный ввод или вывод, это использование объясняется в разделе ОПЕРАНДЫ. В противном случае, если такая утилита использует операнды для представления файлов, определяется реализацией, -означает ли операнд стандартный ввод (или стандартный вывод) или файл с именем -.

Но тогда man 1 bashчитает:

A --сигнализирует об окончании параметров и отключает дальнейшую обработку параметров. Любые аргументы после --них рассматриваются как имена файлов и аргументы. Аргумент -эквивалентен --.

Таким образом, для Bash не -подразумевается ни стандартный ввод, ни файл, следовательно, он несколько нестандартен.

Теперь ваш частный случай:

curl -sL https://rpm.nodesource.com/setup_6.x | sudo -E bash -

Я подозреваю, что автор этой команды, возможно, не понимает -, эквивалентно --в этом случае. Я подозреваю, что автор хотел убедиться, что bashпрочитает из его стандартного ввода, они ожидали, что будут -работать в соответствии с руководящими принципами 13.

Но даже если бы он работал в соответствии с руководящими принципами, здесь не -было бы необходимости, потому что он bashопределяет, когда его стандартный ввод является каналом, и действует соответствующим образом (если -cне указано и т. Д.).

Пока -не работает в соответствии с руководящими принципами, он работает как --. Здесь все еще --не нужно, потому что после него нет аргументов.

На мой взгляд, последнее -ничего не меняет. Команда будет работать без него.

Чтобы увидеть, как --и чем это -может быть полезно в целом, изучите приведенный ниже пример.


catв моем Kubuntu соблюдаются оба правила, и я буду использовать его, чтобы продемонстрировать полезность -и --.

Пусть файл с именем fooсуществует. Это распечатает файл:

cat foo

Пусть файл с именем --helpсуществует. Это не будет печатать файл:

cat --help

Но это напечатает файл с именем --help:

cat -- --help

Это объединит файл с именем, --helpполученным от стандартного ввода:

cat -- --help -

Кажется, вам на самом деле не нужно --, потому что вы всегда можете передать, ./--helpчто наверняка будет интерпретировано как файл. Но посмотрим

cat "$file"

когда вы не знаете заранее, что такое содержимое переменной. Вы не можете просто смириться ./с этим, потому что это может быть абсолютный путь и ./сломать его. С другой стороны, это может быть файл с именем --help(потому что почему бы и нет?). В этом случае --очень полезно; это намного более надежная команда:

cat -- "$file"

6

В man bashконце односимвольных опций есть: -

--    A -- signals the end of options and disables further option processing.
      Any arguments after the -- are treated as filenames and arguments. An
      argument of - is equivalent to --.

Если вы процитировали полную команду, я не вижу никаких оснований для использования -после того, как bashв данном случае, но это не делает никакого вреда.


Спасибо за ваш ответ, да, я процитировал всю команду. поэтому что-либо после - или - будет рассматриваться не как опция, а как имя файла или аргументы, не могли бы вы привести пример, где это полезно?
Омар БИСТАМИ

1
Это действительно для сценария, имя которого начинается -, маловероятное требование, но -/ --делает это возможным.
AFH

1
@OmarBISTAMI Цитирование команды влияет на то, как ее расширяет оболочка, но не влияет ни на один из последующих аргументов. Если вы расширяете кавычки вокруг допустимых аргументов, они становятся частью имени команды, что тоже не то, что вам нужно. Есть некоторые команды, которые принимают имена файлов в качестве аргументов, но по умолчанию не используют стандартный ввод. Придуманный пример позволяет вам сэндвич-ввод (из терминала или канала) между двумя файлами. cat file1 - file2 > file3,
Джо

1
curl -sL https://rpm.nodesource.com/setup_6.x | sudo -E bash -

bash -значит что bashждет stdin. Таким образом, практически bash выполнит все, что возвращается командой слева от|

Аналогичный, но более простой пример:

echo hello | cat - здесь catбудет напечатано «привет». Почему? Потому что "привет" отправляется кошке через |и catждет, что-нибудь отправлено на него

Теперь давайте разберем всю команду на две части:

curl -sL https://rpm.nodesource.com/setup_6.x

эта команда curl вернет что-то, что может быть понято и выполнено bash

то есть труба , |которая будет посылать вывод , возвращаемый командой завитка , чтобы с правой стороны трубы , т.е. sudo -E bash -. Наконец sudo -E bash -, bash готов выполнить все, что ему отправлено

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.