问题理解.sh文件中的'hash'命令


5

所以我想在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 
}

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

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


如果它是“ sh”脚本,为什么还要将其标记为“ bash”?
斯特凡Chazelas

2
因为我不知道区别,对不起。
Yalla T.

Answers:


3

在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表示命令成功运行。


1
好的,谢谢!感谢您的回答,我确实理解了这段代码,并且将问题范围缩小到从sh文件访问$ Path时缺少'node'条目。
Yalla T.

hash node如果node不在PATH上,则返回1;如果尚未进行哈希处理,则返回1。
Lri

hash node如果在Bash中禁用了哈希,则返回1 :)有关详细信息,请参见答案
Evgeny Vereshchagin,2015年

3

除了先前发布的答案之外,我还要添加对“ 2>&1”部分的说明。

> /dev/null

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

2>&1

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

因此,这两个部分都确保从hash命令看不到任何输出。


1

从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在路径中搜索可执行文件。


0

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

使用hash代替它是因为:

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

正如OP在评论中提到的那样,问题在于运行脚本时实际上PATH中缺少该节点。因此which node会有相同的结果。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.