if [ -n "$(which voltdb 2> /dev/null)" ]; 是什么意思?

if [ -n "$(which voltdb 2> /dev/null)" ]; 是什么意思?

我有非常基本的 Linux 技能,现在正在尝试解析一些 shell 脚本。我在其中一个脚本中看到这一行:

if [ -n "$(which voltdb 2> /dev/null)" ];

我知道 /dev/null 是位存储桶,如果我在命令行运行 voltdb,它会打印出将执行的路径。而且,整行显然是一个 if 语句。但我对这里的许多其他事情感到困惑。

  1. 为什么将 2 与 /dev/null 进行比较?这些看起来像是不兼容的类型。
  2. 开关 -n 有何作用?我习惯使用 rm -r filename 等开关,但 -n 似乎不与任何命令配对
  3. 括号有什么作用?他们在这里似乎有别的意思,而不是在这个表达中这个测试表达式[]是什么意思?

基本上,这条线有什么作用?对我来说,这里面有太多的未知数——所以这有点像听到一个外语句子,错过了很多单词,以至于你无法理解基本结构。

答案1

该代码片段中发生了很多事情。从内到外工作:

which voltdb 2> /dev/null- 这里执行的命令是whichwhich调用时,将查找环境变量中的所有条目PATH以查找名为“voltdb”的命令。如果它在 中指定的目录之一中找到名为“voltdb”的可执行文件,它将打印该可执行文件PATH的完全限定名称。voltdb

为了回答你的第一个问题,“2>”是重定向的一个例子。每个 Unix/Linux/*BSD 进程都有 3 个标准输入和输出,0 是 stdin,1 是 stdout,2 是 stderr。在命令行上运行的程序通常会将错误消息打印到 stderr。因此,“2> /dev/null”并不是在数字上比较 2 和“/dev/null”,而是将任何which错误输出发送到/dev/null,一个特殊文件,只接受任何输入,并返回 0 字节的输出。

除此之外,该$(...)构造意味着“运行所包含的命令并按词法替换此处‘$(’和‘)’之间的任何输出”。这就是输出替换,shell 程序所做的事情。

在输出替换之外,片段会执行if [ -n "something" ];,其中“某物”是which要打印的内容。 “if”是 shell 控制流结构,当“if”之后的命令管道以“成功”状态退出时,会导致执行代码块。

实际上是[一个可执行文件,它查看命令行参数直到]. “-n”标志通常意味着“对于非零字符串长度的下一个参数为 true”。这就是你的第二个问题和第三个问题的答案。该[ ... ]构造对某些逻辑条件给出 true(以成功代码退出)或 false(以失败代码退出)答案,在本例中为“非零字符串长度”。

voltdb最终,当该 shell 的 PATH中有一个包含可执行文件的目录时,该片段将执行 if-then-fi 或 if-then-else-fi 控制流的“true”子句。

答案2

该代码正在执行以下操作:

if [ -n "...." ];

如果双引号中的代码执行结果为空,则 if 语句为 true。

双引号内的代码:

$(which voltdb 2> /dev/null)

运行该which voltdb命令并将 STDERR(标准错误)上发生的该命令的任何输出重定向到/dev/null.基本上我们对此不感兴趣,所以我们忽略它。

结果which voltdb将返回 PATH 上与字符串 voltdb 匹配的任何可执行文件的路径。

例子

$ which time
/usr/bin/time

$ which time 2> /dev/null
/usr/bin/time

关于2>

2>是一种速记符号,用于重定向其中之一的输出溪流这是程序运行时自动设置的。流如下:

  • 0 - 标准输入(又名 STDIN)
  • 1 - 标准输出(又名 STDOUT)
  • 2 - 标准错误(又名 STDERR)

因此,如果您想获取 STDERR 的输出并将其删除:

$ which time 2> /dev/null

如果您想从 STDOUT 获取输出并将其重定向到 STDERR:

相关内容