Чому повідомлення про помилку для двох колонок як команди (: :) у bash має три колонки, але одна двокрапка не дає результату?


27

Якщо я набираю

::

в оболонку bash, я отримую:

-bash: ::: command not found

Але лише один :результат не дає результату. Чому це?


Коментарі не для розширеного обговорення; ця розмова перенесена в чат .
Thomas Ward

Як це пов’язано з 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

Таким чином, те, що ви бачите, - це не три кольори, а те, що ви ввели, вставили у стандартний формат помилок.

Зауважте також, що :можуть брати аргументи командного рядка, тобто робити це законно:

: :

У цьому випадку оболонка вважатиме, що це два "слова", одне з яких - команда, а інше - позиційний параметр. Це також не призведе до помилок! (Див. Також історичну записку (пізніше у цій відповіді) про використання параметра :з позиційними параметрами.)


У снарядах, окрім бош

Зауважте, що форматування також може відрізнятися між різними оболонками. Бо 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 () , яка згідно з документацією бере строковий аргумент, потім виводить повідомлення про помилку після двокрапки, а потім новий рядок. Цитата:

Функція 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 і Томпсона :використовували gotoоператор (який, за словами користувача Perderabo, на цій темі не був вбудованою оболонкою). Цитата з посібника:

У всьому файлі команд шукається рядок, що починається з символу: як першого непорожнього символу, після якого - один чи більше пробілів, а потім мітка. Якщо такий рядок знайдений, goto репозиціонує зсув командного файлу у рядок після мітки та виходу. Це змушує оболонку переходити до міченої лінії.

Таким чином, ви можете зробити щось подібне, щоб створити нескінченний сценарій циклу:

: repeat
echo "Hello World"
goto repeat

Друкарська помилка "3 колонки" для "3 колони"
Barmar

1
У DOS command.comі Windows " cmd.exeсхожа, але протилежна ситуація: :явно є готильованою міткою (не командою) і часто переставляється як символ коментаря (наприклад :: This is a comment).
grawity

54

Остання двокрапка - це лише частина типового повідомлення "не знайдено":

$ 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

Дивіться, наприклад, якій цілі служить вбудована кишка?


так, це найбільш вичерпний коментар .. набагато красномовніший, ніж мій .. набагато краще пояснено: D
Джон Оріон

8

Спробуйте будь-яку іншу неіснуючу команду, і ви побачите, що вона :виконує звичайне призначення англійською мовою:

$ ---
---: command not found

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

третій - це прокладка від форматування

у bash a :- пуста рядова інструкція


4

ви отримуєте 3 колонки, оскільки формат помилки містить двокрапку:

bash: <command>: command not found
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.