我正在尝试编写第一个 bash 脚本来安装一堆依赖项,然后执行脚本。
我正在努力与用户 b/c 进行调试,我是一名开发人员,这意味着我已经安装了一堆工具(例如 homebrew、ruby、node 等),并且我的用户全新安装了 OSX。我希望这个脚本能够与所有全新安装 OSX 的新用户一起使用。
我试图PATH
在脚本开头导出一个简单的框架,只是为了调试目的,以模仿用户的全新安装。
我手头的问题是我不确定如何实际引用node
或npm
具体以便我可以运行npm install
.
你可以看到我echo
的正在生产什么。有什么想法如何正确安装 node/npm 然后执行它?
#!/bin/bash
# Install necessary deps and runs script to create user for the DEV environment.
# Mainly used for non engineers to be able to create their own emails.
export PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin::/usr/local
echo $PATH
# Install homebrew
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
# Install node 8
/usr/local/bin/brew install node@8
# Install npm - https://stackoverflow.com/a/36631430/222403
/usr/local/bin/brew postinstall node@8
echo /usr/local/bin/brew --prefix node@8 = $(/usr/local/bin/brew --prefix node@8)
echo which node = $(which node) --> PRINTS which node =
echo which node@8 = $(which node@8) --> PRINTS which node@8 =
echo which npm = $(which npm) --> prints which npm =
....
答案1
Brew 通常将文件安装到/usr/local/Cellar
并将它们符号链接到/usr/local/bin
.
这些$PATH
新盒子上可能没有/usr/local/bin
。所以你有两个选择:
阅读有关冲泡的内容并预测这些包将安装在哪里,检查退出状态,
brew install ...
然后通过更改脚本以包含绝对路径来硬编码brew安装的新二进制文件/脚本的路径。如果
brew install foo
有效,那么foo
二进制文件应该可以用于调用/usr/local/bin/foo
。如果有效的话,这应该会给你一个线索
brew install
:/usr/local/bin/brew install node@8 status=$(echo $?) if [[ "$status" -ne 0 ]]; then echo "Brew install node failed!" exit 1 fi ...
如果你想完全自动化这个脚本,检查调用命令时是否有错误并进行处理。
在脚本尝试依赖系统路径进行命令解析之前更新系统路径。这应该可以解决问题:
#!/bin/bash export PATH="/usr/local/bin:$PATH" ...
这不依赖于用户的 bash 环境,并且应该修复
which
上面的命令。但请考虑一下,您的新盒子/usr/local/bin
到底还需要吗$PATH
?
答案2
假设:我的印象是,一旦您尝试安装 Node 和 NPM,您就会尝试执行它们,而不知道脚本中它们的实际路径。这就是我的回答的基础。
调用节点和NPM:
这行应该可以解决问题:
$(which <command>) <command arguments>
因此,对于某些 NPM 包,您可能会使用:
$(which npm) install <packagename>
这是因为完整路径可执行文件的名称(如果在 bash 中列在其他任何内容之前)就是它将要执行的内容。 “$()”结构实际上会将可执行位置替换为 bash。
例子:
$(which yes) IT WORKS!
这将打印出“IT WORKS!”重复在屏幕上显示,直到被中断。
正如评论中所述,如果您知道 Node 和 NPM 将安装到哪里,那么您也可以使用它们的完整路径来执行它们(尽管请参阅注释以了解更好的方法)。
(如果您需要安装 ruby,则需要您自己,尽管我认为您只需执行类似于“curl”行的操作即可)。
笔记:您的脚本中的 $PATH 变量中已经有了“/usr/local/bin”和“/usr/bin”,因此除非发生了一些奇怪的事情,否则您可以运行“ruby”和“brew”而不指定它们的完整内容路径。
答案3
添加: 怎么找node
。
我建议您卸载node@8并使用--verbose
选项重新安装node@8。
brew uninstall node@8
brew install --verbose node@8
它可能会显示安装步骤。从输出中,我希望您可以找到 的位置node
及其符号链接。
或者,
您可以使用命令从节点包中找到已安装文件的路径brew list
。
brew list node@8
它显示了所有已安装的文件。
然后,如果你可以使用 GNU find
,它可以找到某个文件的符号链接。
find -L /dir/to/start/find -samefile /the/path/of/the/original/file
如果找到brew制作的node的符号链接,请将路径添加到$PATH中。如果不存在符号链接,则应自行创建符号链接或添加原始文件的路径node
。
由于误解问题而产生的答案:如何使用which
和变量
我将路径分配给变量,如下所示:
#!/bin/bash
NODE=`which node`
NPM=`which npm`
echo "Node.js path: ${NODE}"
$NODE -v
echo "npm path: ${NPM}"
$NPM -v
笔记: `which node`
等于$(which node)
. Backticks(backquotes) 和 $() 返回结果。
which
返回命令的完整路径,因此`which node`
返回node.js的安装路径。并将其分配给$NODE
变量。