具有有限路径的 Bash 脚本

具有有限路径的 Bash 脚本

我正在尝试编写第一个 bash 脚本来安装一堆依赖项,然后执行脚本。

我正在努力与用户 b/c 进行调试,我是一名开发人员,这意味着我已经安装了一堆工具(例如 homebrew、ruby、node 等),并且我的用户全新安装了 OSX。我希望这个脚本能够与所有全新安装 OSX 的新用户一起使用。

我试图PATH在脚本开头导出一个简单的框架,只是为了调试目的,以模仿用户的全新安装。

我手头的问题是我不确定如何实际引用nodenpm具体以便我可以运行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。所以你有两个选择:

  1. 阅读有关冲泡的内容并预测这些包将安装在哪里,检查退出状态,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
    ...
    

    如果你想完全自动化这个脚本,检查调用命令时是否有错误并进行处理

  2. 在脚本尝试依赖系统路径进行命令解析之前更新系统路径。这应该可以解决问题:

    #!/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变量。

相关内容