Background: I'm trying to get nvm
to setup up node
correctly in a non-login shell via the shebang at the top of the node script.
The shebang for a node script in the login shell
is:
#!/usr/bin/env node
This doesn't work for non-login shell
so I want to do the equivalent of:
#!/usr/bin/env [[ -s $HOME/.nvm/nvm.sh ]] && source "$HOME/.nvm/nvm.sh" && node
But I'm not able to get the syntax correct (see below for error). I've tried several ways, including quoting the script or trying to run it bash -c
. But each time I'm facing parsing errors.
The full script is:
#!/usr/bin/env node
const semver = require('semver');
console.log("Hello World! You're using " process.version)
Errors:
in the login shell (where I don't need it)
❯ bin/nodesample.js
env: [[: No such file or directory
in the non login shell where I want to find a solution for
env: [[: No such file or directory
If I try #!/usr/bin/env "[[ -s $HOME/.nvm/nvm.sh ]] && source "$HOME/.nvm/nvm.sh" && node"
env: "[[: No such file or directory
CodePudding user response:
The shebang is not well suited to running complex commands. It's job is just to tell the kernel what interpreter you want to use for the script. It's not executed in your shell, so concepts like [[
or &&
or even $parameter
won't exist. In your error messages, env
is telling you it wants a command it can find on your path and [[
is a bash keyword so that won't work.
The standard solution if you need to do some setup before running your command is a wrapper script, like Julien suggested.
#!/usr/bin/env bash
[[ -s $HOME/.nvm/nvm.sh ]] && source "$HOME/.nvm/nvm.sh" && node bin/nodesample.js
You could even go one step further and install a wrapper script that you can then use on the shebang line of other node scripts.
#!/usr/bin/env bash
# nodewrapper script - place in e.g. /bin
[[ -s $HOME/.nvm/nvm.sh ]] && source "$HOME/.nvm/nvm.sh" && exec node "${@}"
#!/bin/nodewrapper
const semver = require('semver');
console.log("Hello World! You're using " process.version)
CodePudding user response:
[[: No such file or directory
Double left brackets is the built in test available in bash and zsh.
Normally test is /bin/[
. But the [[
has no binary associated.
This error is reporting that it could not find [[
in your path.
#!/usr/bin/env [[ -s $HOME/.nvm/nvm.sh ]] && source "$HOME/.nvm/nvm.sh" && node
That can not work. You should reformat it this way:
#!/usr/bin/env bash
[[ -s $HOME/.nvm/nvm.sh ]] && source "$HOME/.nvm/nvm.sh" && node << EOF
const semver = require('semver');
console.log("Hello World! You're using " process.version)
EOF
Test as working:
$ ./left
Hello World! You're using v18.9.0