NerdOfLinux Asked: 2017-12-15 17:18:31 +0800 CST2017-12-15 17:18:31 +0800 CST 2017-12-15 17:18:31 +0800 CST 为什么bash中两个冒号作为命令(::)的错误消息有三个冒号,但是一个冒号没有输出? 772 如果我输入 :: 进入 bash shell,我得到: -bash: ::: command not found 但是,只有一个:导致没有输出。为什么是这样? command-line 6 个回答 Voted steeldriver 2017-12-15T17:30:44+08:002017-12-15T17:30:44+08:00 最后一个冒号只是默认“未找到”消息的一部分: $ 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 例如,请参阅内置冒号的用途是什么? Best Answer Sergiy Kolodyazhnyy 2017-12-15T17:33:19+08:002017-12-15T17:33:19+08:00 shell:内置 vs 不存在:: : 存在shell 内置命令(注意外部命令和内置命令之间的区别),它什么都不做;它只是返回成功,就像true命令一样。:内置是标准的,由POSIX 标准定义,它也被称为“空实用程序”。它经常用于测试或运行无限循环,如while : ; do ...;done bash-4.3$ type : : is a shell builtin 但是,::- 两个冒号字符一起 - 被解释为 shell 的一个“单词”,它假定是用户输入的命令。shell 将检查内置程序,然后检查PATH变量中的任何目录是否存在该命令。但是既没有内置:: 也没有外部命令::。因此,这会产生错误。 那么,错误的典型格式是什么? <shell>: <command user typed>: error message 因此,您看到的不是 3 个冒号,而是您键入的内容粘贴到标准错误格式中。 另请注意,这:可以采用命令行参数,即这样做是合法的: : : 在这种情况下,shell 会将其视为两个“单词”,其中一个是命令,另一个是位置参数。这也不会产生错误!(另请参阅有关使用:位置参数的历史注释(本答案后面)。) 在 bash 以外的 shell 中 请注意,不同外壳之间的格式也可能有所不同。对于bash, ksh, 和mksh行为是一致的。例如,Ubuntu 的默认/bin/shshell(实际上是/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. 错误信息 通常,错误消息中的第一项应该是正在执行的进程或函数(您的 shell 尝试执行::,因此错误消息来自 shell)。例如,这里的执行过程是stat: $ stat noexist stat: cannot stat 'noexist': No such file or directory 事实上,POSIX 定义了perror()函数,根据文档,它接受一个字符串参数,然后在冒号后输出错误消息,然后是换行符。引用: perror() 函数应将通过符号 errno 访问的错误号映射到与语言相关的错误消息,该错误消息应写入标准错误流,如下所示: 首先(如果 s 不是空指针并且 s 指向的字符不是空字节),s 指向的字符串后跟冒号和 <space>。 然后是一个错误消息字符串,后跟一个 <换行符>。 从技术上讲,字符串参数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 shell 中,:使用了 withgoto语句(根据该线程上名为 Perderabo 的用户所说,它不是内置的 shell)。从手册中引用: 在整个命令文件中搜索以 : 开头的行作为第一个非空白字符,然后是一个或多个空格,然后是标签。如果找到这样的行,goto 将命令文件偏移重新定位到标签之后的行并退出。这会导致 shell 转移到标记的行。 所以你可以做这样的事情来制作一个无限循环脚本: : repeat echo "Hello World" goto repeat Olorin 2017-12-15T17:29:53+08:002017-12-15T17:29:53+08:00 尝试任何其他不存在的命令,你会发现:它在英语中达到了正常的目的: $ --- ---: command not found user688056 2017-12-15T17:30:42+08:002017-12-15T17:30:42+08:00 $ :: bash: ::: command not found $ kkkk bash: kkkk: command not found 第三个是格式化的间隔 在 bash a:中是一个空行 void 指令 John Orion 2017-12-15T17:31:26+08:002017-12-15T17:31:26+08:00 添加的冒号是错误消息本身的一部分。cd ow如果它导致一种类型bash: cd: ow: No such file or directory,这表明错误是在额外的冒号中: No such file or directory ravery 2017-12-15T17:31:28+08:002017-12-15T17:31:28+08:00 你得到 3 个冒号,因为错误格式包含一个冒号: bash: <command>: command not found
最后一个冒号只是默认“未找到”消息的一部分:
一个冒号什么都不产生的原因是它
:
是一个有效的命令——尽管它什么都不做(除了 returnTRUE
)。从SHELL BUILTIN COMMANDS
部分man bash
:您有时会在结构中看到它,例如
例如,请参阅内置冒号的用途是什么?
shell
:
内置 vs 不存在::
:
存在shell 内置命令(注意外部命令和内置命令之间的区别),它什么都不做;它只是返回成功,就像true
命令一样。:
内置是标准的,由POSIX 标准定义,它也被称为“空实用程序”。它经常用于测试或运行无限循环,如while : ; do ...;done
但是,
::
- 两个冒号字符一起 - 被解释为 shell 的一个“单词”,它假定是用户输入的命令。shell 将检查内置程序,然后检查PATH
变量中的任何目录是否存在该命令。但是既没有内置::
也没有外部命令::
。因此,这会产生错误。那么,错误的典型格式是什么?
因此,您看到的不是 3 个冒号,而是您键入的内容粘贴到标准错误格式中。
另请注意,这
:
可以采用命令行参数,即这样做是合法的:在这种情况下,shell 会将其视为两个“单词”,其中一个是命令,另一个是位置参数。这也不会产生错误!(另请参阅有关使用
:
位置参数的历史注释(本答案后面)。)在 bash 以外的 shell 中
请注意,不同外壳之间的格式也可能有所不同。对于
bash
,ksh
, 和mksh
行为是一致的。例如,Ubuntu 的默认/bin/sh
shell(实际上是/bin/dash
):其中 1 是命令号(相当于脚本中的行号)。
csh
相比之下,根本不产生错误消息:实际上,如果您运行
strace -o csh.trace csh -c ::
,csh.trace
文件中的跟踪输出会显示csh
以退出状态 0 退出(没有错误)。但是tcsh
会输出错误(但不输出其名称):错误信息
通常,错误消息中的第一项应该是正在执行的进程或函数(您的 shell 尝试执行
::
,因此错误消息来自 shell)。例如,这里的执行过程是stat
:事实上,POSIX 定义了perror()函数,根据文档,它接受一个字符串参数,然后在冒号后输出错误消息,然后是换行符。引用:
从技术上讲,字符串参数
perror()
可以是任何东西,但为了清楚起见,它通常是函数名或argv[0]
.相比之下, GNU 有自己的一组用于错误处理的函数和变量,程序员可以使用这些函数和变量
fprintf()
进行stderr
流式处理。正如链接页面上的示例之一所示,可以执行以下操作:历史记录
在旧的 Unix 和 Thompson shell 中,
:
使用了 withgoto
语句(根据该线程上名为 Perderabo 的用户所说,它不是内置的 shell)。从手册中引用:所以你可以做这样的事情来制作一个无限循环脚本:
尝试任何其他不存在的命令,你会发现
:
它在英语中达到了正常的目的:第三个是格式化的间隔
在 bash a
:
中是一个空行 void 指令添加的冒号是错误消息本身的一部分。
cd ow
如果它导致一种类型bash: cd: ow: No such file or directory
,这表明错误是在额外的冒号中: No such file or directory
你得到 3 个冒号,因为错误格式包含一个冒号: