Home > Mobile >  What is the correct syntax for executing bash script in a shebang executing in a non login shell
What is the correct syntax for executing bash script in a shebang executing in a non login shell

Time:09-20

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
  • Related