I have written a simple script.
When I run
sh <myscriptname.sh>, i got the correct output, but when I run
./<myscriptname.sh>, I got an error.
What is difference between when I do
When you run any script by passing the filename to the script interpreter program, you are running the interpreter program with the script as an argument passed into it. For example this would look like the process 'sh' with the argument 'filename.sh'. The
On the other hand if you run the script itself, the system calls out to the interpreter program specified and feeds in the scripts contents. In this case the process looks like 'filename.sh' with no arguments.
You should make sure you have a bang line:
A bang line is the very first line in the script and starts with the same two characters
Once you have your script, make sure you have set execute permissions:
Then you can run the script as its own process:
Or put the file into a known location with a nice program name, like
And this is really the practical benefit of using the bang line with the right permissions - it's all about deployment. It's very hard to get users to run a script if they have to remember what program to run the script with. Remember to give a full path to the script every time they want to run it. Where as putting it in
It's also good for identification. If you go into the
Note: If you want to distribute a script that's accessible to everyone, then please create a man page and a deb package to install it. We need to reduce the number of random scripts online and increase the number of debs which can be uninstalled.
The short version:
There are three main reasons you might be getting an error:
If your first line looks right, but still isn't working, make sure the file doesn't have DOS line endings.
The error would look something like this:
You can fix it by running
The difference you do is,
And the answer is that sh is name for very popular shell. But outdated and replaced by others. Nowadays sh is linked to others shells installed on machine. e.g. I have bash putted there. Running any shell from sh usually trigger some 'compatibility' mode with original 'shell' behavior.
So solution is quite simple. Look what's behind sh command (ls -al /bin/sh), and put #!/bin/whatever_you_find_there as first line (or if there is something like that in your script edit it).
And alternatively there may be some bug in script itself. Like dependence that is met by sh, but not interpreter that is actually used.