Что означает «-» в «bash -»?

33

Что bash -означает следующий код оболочки bash? Кажется, он используется для вывода последнего кода в качестве ввода. Если так, я могу просто написать это как bashили xargs bash?

curl --silent --location https://rpm.nodesource.com/setup | bash -
Searene
источник

Ответы:

36

Если есть сомнения, прочитайте исходный код. знак равно

Bash 4.3, shell.cстрока 830, в функцииparse_shell_options() :

  /* A single `-' signals the end of options.  From the 4.3 BSD sh.
     An option `--' means the same thing; this is the standard
     getopt(3) meaning. */
  if (arg_string[0] == '-' &&
       (arg_string[1] == '\0' ||
         (arg_string[1] == '-' && arg_string[2] == '\0')))
    return (next_arg);

Другими словами, -говорят, что больше нет вариантов . Если бы в командной строке было больше слов, они были бы обработаны как имя файла, даже если слово начиналось с символа -.

В вашем примере, конечно, это -полностью избыточно, так как в любом случае за ним ничего не следует. Другими словами, bash -это точно эквивалентноbash .


Баш принимает свои команды

  1. из файла сценария, если он указан в командной строке, или
  2. неинтерактивно со своего стандартного ввода, если его стандартный вывод не является TTY (например, в вашем примере: стандартный ввод - это канал, поэтому Bash выполнит содержимое этого URL-адреса в виде сценария), или
  3. интерактивно, если его стандартный ввод - TTY.

Это неправильное представление, которое bash -говорит Bash читать его команды из стандартного ввода. Несмотря на то , что это правда , что в вашем примере, Bash будет читать свои команды из стандартного ввода, он сделал бы так , независимо от того, существует ли -в командной строке, поскольку, как было указано выше, bash -является идентичным bash.

Чтобы дополнительно проиллюстрировать, что -это не означает stdin, рассмотрим:

  • Команда catпредназначена для интерпретации -как stdin. Например:

    $ echo xxx | cat /etc/hosts - /etc/shells
    127.0.0.1 localhost
    xxx
    # /etc/shells: valid login shells
    /bin/sh
    /bin/dash
    /bin/bash
    /bin/rbash
    /bin/zsh
    /usr/bin/zsh
    /usr/bin/screen
    /bin/tcsh
    /usr/bin/tcsh
    /usr/bin/tmux
    /bin/ksh93
  • В отличие от этого, вы не можете заставить Bash выполнить /bin/dateтогда /bin/hostname, попробовав это:

    $ echo date | bash - hostname
    /bin/hostname: /bin/hostname: cannot execute binary file

    Скорее, он пытается интерпретировать его /bin/hostnameкак файл сценария оболочки, который терпит неудачу, потому что это набор двоичных бредовых книг.

  • Вы не можете выполнить, date +%sиспользуя bash -либо.

    $ date +%s
    1448696965
    $ echo date | bash -
    Sat Nov 28 07:49:31 UTC 2015
    $ echo date | bash - +%s
    bash: +%s: No such file or directory

Вы можете написать xargs bashвместо этого? No. curl | xargs bashвызовет bash с содержимым скрипта в качестве аргументов командной строки. Первое слово содержимого будет первым аргументом, и, скорее всего, оно будет неверно истолковано как имя файла сценария.

200_success
источник
6
upvote за единственный правильный ответ.
гейра
В самом деле: по словам руководстваAn argument of - is equivalent to --.
Steeldriver
Если вы действительно хотите использовать xargsвместо этого, он будет работать (в ограниченном сценарии достаточно маленького входного скрипта) с | xargs bash -c; но на самом деле, это не полезное или идиоматическое использование xargs.
tripleee
@tripleee Если содержимое URL-адреса больше, чем однострочный, то разрывы строк и другие разделители, вероятно, будут неправильными.
200_успех
Да, ты прав, конечно.
tripleee