Почему сообщение об ошибке для двух двоеточий в качестве команды (: :) в bash имеет три двоеточия, но одно двоеточие не дает вывода?

27

Если я наберу

::

в оболочку bash, я получаю:

-bash: ::: command not found

Но только один :результат не приводит к выводу. Почему это?

NerdOfLinux
источник
Комментарии не для расширенного обсуждения; этот разговор был перемещен в чат .
Томас Уорд
Как это связано с Ubuntu?
NerdOfCode
@NerdOfCode так же, как это? meta.askubuntu.com/q/17076/158442
Муру

Ответы:

40

:Оболочка встроенная против несуществующего::

Существует : встроенная команда оболочки (обратите внимание на разницу между внешней и встроенной командами ), которая ничего не делает; он просто возвращает успех, как trueкоманда. :Встроенный стандартный и определяется стандартом POSIX , где он также известен как «нулевой полезности». Он часто используется для тестирования или для запуска бесконечных циклов, как вwhile : ; do ...;done

bash-4.3$ type :
: is a shell builtin

Тем не менее, ::- два символа двоеточия вместе - интерпретируются как одно «слово» для оболочки, и предполагается, что это команда, введенная пользователем. Оболочка будет проходить процесс проверки встроенных модулей, а затем любого каталога в PATHпеременной на наличие этой команды. Но нет ни встроенной, :: ни внешней команды ::. Следовательно, это приводит к ошибке.

Ну, что является типичным форматом для ошибки?

<shell>: <command user typed>: error message

Таким образом, вы видите не 3 двоеточия, а то, что вы ввели, вставлены в стандартный формат ошибок.

Также обратите внимание, что он :может принимать аргументы командной строки, то есть это допустимо:

: :

В этом случае оболочка будет рассматривать это как два «слова», одно из которых является командой, а другое позиционным параметром. Это также не приведет к ошибке! (См. Также историческую заметку (далее в этом ответе) об использовании of :с позиционными параметрами.)


В снарядах, кроме Баш

Обратите внимание, что форматирование также может отличаться для разных оболочек. Ибо bash, kshи mkshповедение является последовательным. Например, /bin/shоболочка по умолчанию Ubuntu (которая на самом деле /bin/dash):

$ dash
$ ::
dash: 1: ::: not found

где 1 - номер команды (эквивалентный номеру строки в скрипте).

csh напротив, вообще не выдает сообщения об ошибке:

$ csh
% ::
%

Фактически, если вы запустите strace -o csh.trace csh -c ::, вывод трассировки в csh.traceфайле показывает, что cshвыходы завершаются со статусом выхода 0 (без ошибок). Но tcshвыводит ли ошибку ( но не выводит ее имя):

$ tcsh
localhost:~> ::
::: Command not found.

Сообщения об ошибках

Как правило, первый элемент в сообщении об ошибке должен быть исполняющим процессом или функцией (ваша оболочка пытается выполнить ::, следовательно, сообщение об ошибке приходит из оболочки). Например, здесь выполняющийся процесс stat:

$ stat noexist
stat: cannot stat 'noexist': No such file or directory

Фактически, POSIX определяет функцию perror () , которая в соответствии с документацией принимает строковый аргумент, затем выводит сообщение об ошибке после двоеточия, а затем перевод строки. Quote:

Функция perror () должна отобразить номер ошибки, к которому осуществляется доступ через символ errno, в сообщение об ошибке, зависящее от языка, которое должно быть записано в стандартный поток ошибок следующим образом:

  • Во-первых (если s не является нулевым указателем и символ, на который указывает s, не является нулевым байтом), строка, на которую указывает s, сопровождается двоеточием и <пробелом>.

  • Затем строка сообщения об ошибке, за которой следует <newline>.

И в качестве аргумента строки perror()технически может быть что угодно, но, конечно, для ясности обычно это имя функции или argv[0].

В отличие от этого, GNU имеет свой собственный набор функций и переменных для обработки ошибок , которые программист может использовать fprintf()для stderrпотоковой передачи. Как показывает один из примеров на связанной странице, можно сделать что-то вроде этого:

  fprintf (stderr, "%s: Couldn't open file %s; %s\n",
           program_invocation_short_name, name, strerror (errno));

Историческая справка

В старых Unix и Thompson оболочка :использовалась с gotoоператором (который, по словам пользователя Perderabo в этом потоке, не был встроенным в оболочку). Цитата из руководства:

Во всем командном файле ищется строка, начинающаяся с: как первый непустой символ, за которым следуют один или несколько пробелов, а затем метка. Если такая строка найдена, goto перемещает смещение командного файла на строку после метки и завершает работу. Это заставляет оболочку переходить на помеченную строку.

Таким образом, вы можете сделать что-то вроде этого, чтобы создать скрипт с бесконечным циклом:

: repeat
echo "Hello World"
goto repeat
Сергей Колодяжный
источник
Опечатка "3 колонки" для "3
колон
1
DOS command.comи Windows cmd.exeимеют похожую, но противоположную ситуацию: :это явно метка goto (не команда) и часто используется как символ комментария (например :: This is a comment).
Гравитация
54

Последнее двоеточие является частью стандартного сообщения «not found»:

$ x
x: command not found
$ ::
::: command not found

Причина , по которой единственное двоеточию ничего не производит, что : является допустимой командой - хотя она ничего не делает (кроме возврата TRUE). Из SHELL BUILTIN COMMANDSраздела man bash:

   : [arguments]
          No effect; the command does nothing beyond  expanding  arguments
          and  performing any specified redirections.  A zero exit code is
          returned.

Вы иногда будете видеть это в конструкциях, таких как

while :
do
  something
done

Посмотрите, например, для чего служит встроенное двоеточие?

steeldriver
источник
да, это самый полный комментарий .. гораздо более красноречивый, чем мой .. гораздо лучше объяснил: D
Джон Орион
8

Попробуйте любую другую несуществующую команду, и вы увидите, что она :выполняет свое обычное назначение на английском языке:

$ ---
---: command not found
OLORIN
источник
6

Добавленное двоеточие является частью самого сообщения об ошибке. Если один из cd owних приводит к результату bash: cd: ow: No such file or directory, это показывает, что ошибка помещается в лишний: No such file or directory

Джон Орион
источник
6
$ ::
bash: ::: command not found
$ kkkk
bash: kkkk: command not found

3-й это проставка от форматирования

в bash :- пустая строка

user688056
источник
4

вы получаете 3 двоеточия, потому что формат ошибки содержит двоеточие:

bash: <command>: command not found
ravery
источник