理解 .sh 文件中的“hash”命令时出现问题

理解 .sh 文件中的“hash”命令时出现问题

所以我想在 Linux 机器上安装 Etherpad lite。如果我尝试运行它,我会收到错误:

“请安装node.js(http://nodejs.org)”

该命令which node为我提供了节点js的正确路径。所以我进入了 Etherpad Lite 的 .sh 文件并发现了这个:

  #Is node installed?
  hash node > /dev/null 2>&1 || { 
  echo "Please install node.js ( http://nodejs.org )" >&2
  exit 1 
}

我猜这意味着:检查节点 --> 如果没有可用的打印行并退出。但这段代码到底做了什么?哈希有什么作用?所有这些&和 是怎么回事>

谁能向我解释这三行,我将不胜感激?

答案1

当您在 bash shell 中键入命令时,shell 会在整个 $PATH 变量中查找这些命令。哈希只是您键入的命令以及它们在何处找到的索引,以帮助加快下次查找它们的速度。

笔记: @Anthon的回答给出了哈希是什么的一个很好的定义!

例如,如果您仅运行hash不带参数的命令,您将获得之前找到的命令以及它们被使用的次数(即:点击)的列表:

% hash
hits    command
   2    /usr/bin/host
   1    /bin/more
   1    /home/saml/bin/autossh_mail.sh
   3    /usr/bin/zip
   2    /bin/rm
   2    /bin/date
   2    /usr/bin/vim
   1    /usr/bin/htop
   2    /bin/mv
   3    /bin/ps
   8    /usr/bin/ssh
   1    /usr/bin/yum
   1    /usr/bin/xfreerdp
   1    /bin/cp
   2    /bin/mkdir
   4    /usr/bin/man
   1    /usr/bin/gvim
   1    /usr/bin/unzip
   1    /usr/bin/w
   5    /usr/bin/nslookup
  51    /bin/ls
  15    /usr/bin/find

该命令hash node返回一个状态值(0 或 1),具体取决于该值是否存在于哈希列表中:

hash node不在我的名单上

% hash node
bash: hash: node: not found
% echo $?
1

笔记:任何先前运行的命令的状态都临时存储在环境变量中$?。这是在执行每个命令后放置状态(0 = 成功,1 = 失败)的位置。

构造“cmd1”|| { "cmd2" ... } 是一个 or 语句。在这里思考和/或从逻辑出发。所以这意味着做第一件事,如果失败,那么做第二件事,否则不做第二件事。

一个更详细的例子:

% true && echo "1st cmd ret. 1" || echo "1st cmd ret. 0"
1st cmd ret. 1

% false && echo "1st cmd ret. 1" || echo "1st cmd ret. 0"
1st cmd ret. 0

逻辑总是令人困惑(至少对我来说),因为返回 1 表示命令失败,而返回 0 表示命令运行成功。

答案2

除了之前发布的答案之外,我想添加对“2>&1”部分的解释。

> /dev/null

将输出文件描述符(文件描述符是进程用于读取和写入文件、管道和终端的数字)重定向到文件 /dev/null,该文件是系统的“垃圾罐”,因为它读取任何内容写入它,并丢弃该数据。

2>&1

将编号为 2 的 stderr(错误的输出“文件”)文件描述符重定向到文件描述符 1,该描述符刚刚重定向到 /dev/null,即被忽略。

因此,这两个部分一起确保哈希命令看不到任何输出。

答案3

来自 bash 手册:

Each time hash is invoked, the full pathname of the command name
is  determined  by searching the directories in $PATH and remembered.  
Any previously-remembered pathname is discarded.

hash是 bash 的内部命令,用于使用哈希表bash来查找您键入的命令的完整路径。

该脚本使用它来确保node在路径中搜索可执行文件。

答案4

hash node在 PATH 中搜索第一个名为 node 的命令,并在记住的位置列表中添加或更新节点的位置,如果未找到节点,则返回 1。

使用 hash 代替 which 是因为:

  • 这不是 POSIX 定义的。
  • 在某些环境中,这是一个可以更改 PATH 的 csh 脚本。
  • 例如,在 bash 中,哈希是内置的,但它不是,并且哈希通常更快。

正如评论中提到的那样,问题是运行脚本时节点实际上从 PATH 中丢失。所以which node会得到相同的结果。

相关内容