在非登录 shell 中执行的 shebang 中执行 bash 脚本的正确语法是什么

Pre*_*gha 3 bash shell nvm

背景:我试图通过节点脚本顶部的 shebang 在非登录 shell 中正确nvm设置。node

\n

节点脚本的 shebang 是login shell

\n
#!/usr/bin/env node   \n
Run Code Online (Sandbox Code Playgroud)\n

这不起作用,non-login shell所以我想做相当于:

\n
#!/usr/bin/env [[ -s $HOME/.nvm/nvm.sh ]] && source "$HOME/.nvm/nvm.sh" && node\n
Run Code Online (Sandbox Code Playgroud)\n

但我无法获得正确的语法(请参阅下面的错误)。我尝试了多种方法,包括引用脚本或尝试运行它bash -c。但每次我都会遇到解析错误。

\n

完整的脚本是:

\n
#!/usr/bin/env node\n\nconst semver = require('semver');\nconsole.log("Hello World! You're using " + process.version)\n
Run Code Online (Sandbox Code Playgroud)\n

错误:

\n

在登录 shell 中(我不需要它)

\n
\xe2\x9d\xaf bin/nodesample.js\nenv: [[: No such file or directory\n
Run Code Online (Sandbox Code Playgroud)\n

在非登录外壳中我想找到解决方案

\n
env: [[: No such file or directory\n
Run Code Online (Sandbox Code Playgroud)\n

如果我尝试#!/usr/bin/env "[[ -s $HOME/.nvm/nvm.sh ]] && source "$HOME/.nvm/nvm.sh" && node"

\n
env: "[[: No such file or directory\n
Run Code Online (Sandbox Code Playgroud)\n

tjm*_*772 5

shebang 不太适合运行复杂的命令。它的工作只是告诉内核你想为脚本使用什么解释器。它不在您的 shell 中执行,因此像[[or&&或这样的概念甚至$parameter不会存在。在您的错误消息中,env告诉您它需要一个可以在您的路径上找到的命令,并且[[是 bash 关键字,因此不起作用。

如果您需要在运行命令之前进行一些设置,则标准解决方案是包装脚本,就像 Julien 建议的那样。

#!/usr/bin/env bash
[[ -s $HOME/.nvm/nvm.sh ]] && source "$HOME/.nvm/nvm.sh" && node bin/nodesample.js
Run Code Online (Sandbox Code Playgroud)

您甚至可以更进一步,安装一个包装器脚本,然后可以在其他节点脚本的 shebang 行上使用该脚本。

#!/usr/bin/env bash
# nodewrapper script - place in e.g. /bin
[[ -s $HOME/.nvm/nvm.sh ]] && source "$HOME/.nvm/nvm.sh" && exec node "${@}"
Run Code Online (Sandbox Code Playgroud)
#!/bin/nodewrapper
const semver = require('semver');
console.log("Hello World! You're using " + process.version)
Run Code Online (Sandbox Code Playgroud)