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

Если я наберу

::

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

-bash: ::: command not found

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

27
задан 17 December 2017 в 10:31

6 ответов

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

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

bash-4.3$ type :
: is a shell builtin

Однако :: - два символа двоеточия вместе - интерпретируются как одно "слово" к оболочке, и это принимает, чтобы быть командой вводимый пользователь. Оболочка пройдет процесс созданной-ins проверки, затем любой каталог в PATH переменная для существования той команды. Но нет ни один встроенного :: ни внешняя команда ::. Поэтому это производит ошибку.

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

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

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

Отметьте также, это : может взять параметры командной строки, т.е. законно сделать:

: :

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


В оболочках кроме удара

Обратите внимание, что форматирование может варьироваться между различными оболочками также. Для bash, ksh, и mksh поведение последовательно. Например, значение по умолчанию Ubuntu /bin/sh оболочка (который является на самом деле /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 () функция, которая согласно документации берет аргумент строки, затем выходное сообщение об ошибке после двоеточия и затем новой строки. Кавычка:

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

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

  • Затем строка сообщения об ошибке, сопровождаемая <новая строка>.

И аргумент строки к 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 на этом потоке не был встроенной оболочкой). Кавычка из руководства:

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

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

: repeat
echo "Hello World"
goto repeat
40
ответ дан 17 December 2017 в 10:31

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

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

Причина, по которой одиночное двоеточие ничего не дает, заключается в том, что : является допустимая команда - хотя она ничего не делает (кроме return 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

. См., Например, . ?

54
ответ дан 17 December 2017 в 10:31

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

$ ---
---: command not found
8
ответ дан 17 December 2017 в 10:31
$ ::
bash: ::: command not found
$ kkkk
bash: kkkk: command not found

3-й разделитель из форматирования

в bash a : - пустая инструкция пустых строк

5
ответ дан 17 December 2017 в 10:31

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

bash: <command>: command not found
4
ответ дан 17 December 2017 в 10:31

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

6
ответ дан 17 December 2017 в 10:31

Другие вопросы по тегам:

Похожие вопросы: