所以我想在 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
会得到相同的结果。