I want to use .sh script for deployment of my app. That script is on my home server (Ubuntu 15.10 Server), marked as executable. Access to this script is done through ssh, using this tutorial, I have set up ssh login, that runs that script. So basically I just call ssh someArguments and it runs my script with someArguments as parameters. The user deployer has uid=0, so its basically root (this will be changed in the future, I have set it only to eliminate permissions problems until it works fine).
And here is where the things get tricky. The script reports /usr/bin/env: php: No such file or directory at command /bin/composer install (using Composer). Things are more weird the more I look on that script. Before this line, there is also called /bin/composer self-update and /bin/composer -V, which both runs correctly and displays correct output.
I have checked following things:
/usr/bin/env php -vdisplays correct PHP version (same as/usr/bin/php -v)whereis phpdisplaysphp: /usr/bin/php /usr/local/bin/php /usr/share/man/man1/php.1.gzphp5-clipackage is installed and newest version$PATHcontains/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/gameswhich envdisplays/usr/bin/env
I have also tried following things:
- running the script directly as
bash deploy.shunder root (since it is same as that user) - works perfectly without errors - running failing commands directly - also perfectly without errors
So this seems to me as very specific case, why this command does not work. I spent 12 hours of debugging it and I am out of ideas here.
P.S.: Similar error (/usr/bin/env: node: No such file or directory) occurs when there is bower install (using Bower), but not when running npm install (using NPM).
6 Answers
Make sure that line endings and/or invisible spaces aren't causing the problem.
Remove the spaces in the first line of the script and insert new ones, making sure not to hold CTRL while pressing space.
Also, make sure you don't have DOS line endings (CR+LF). See for details.
The env command will look through a user's $PATH to find the first executable of the given name. So, /usr/bin/env php will look for an executable file called php in any of the directories in the $PATH of the user running it.
In your case, that's almost certainly because when running a command over ssh, you don't start a full shell and don't actually read your shell's initialization files. You can check this by running this command (note the single quotes):
ssh 'echo $PATH'
And comparing the output to what you get if you ssh and then run echo $PATH. On my system. for example:
$ echo $PATH
/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:
$ ssh localhost 'echo $PATH'
/usr/bin:/bin:/usr/sbin:/sbin
Therefore, the $PATH that your script has access to when run with ssh is not the same as when you log in to test it.
In any case, the simple solution is to use the full path to the interpreter instead of env. Both env and full paths have their benefits and drawbacks but, in this case, the path is safer:
#!/usr/bin/php
Easiest way.... change the user's shell as the script.
/etc/passwd
Before:
deploy:x:0:0:,,,:/root:/bin/bash
After:
deploy:x:0:0:,,,:/root:/scripts/deploy.sh
Example script (make sure execute bit is set chmod +x)