views:

691

answers:

3

I have a script that looks like this

#!/bin/bash

function something() {
 echo "hello world!!"
}

something | tee logfile 

I have set the execute permission on this file and when I try running the file like this

 $./script.sh

it runs perfectly fine, but when I run it on the command line like this

$sh script.sh 

It throws up an error. Why does this happen and what are the ways in which I can fix this.

+11  A: 

Running it as ./script.sh will make the kernel read the first line (the shebang), and then invoke bash to interpret the script. Running it as sh script.sh uses whatever shell your system defaults sh to (on Ubuntu this is Dash, which is sh-compatible, but doesn't support some of the extra features of Bash).

You can fix it by invoking it as bash script.sh, or if it's your machine you can change /bin/sh to be bash and not whatever it is currently (usually just by symlinking it - rm /bin/sh && ln -s /bin/bash /bin/sh). Or you can just use ./script.sh instead if that's already working ;)

If your shell is indeed dash and you want to modify the script to be compatible, https://wiki.ubuntu.com/DashAsBinSh has a helpful guide to the differences. In your sample it looks like you'd just have to remove the function keyword.

Chris Smith
It is not the shell that reads the first line of the script but the kernel via one of the exec() system calls.
Beano
To be a bit more generic, the kernel looks for a hash-bang construct on the first line of the script and runs the interpreter (i.e. the shell) named on that line (along with the options that come after the interpreter). The OP specified that the hash-bang was `#!/bin/bash`, so the kernel starts *bash*. Likewise the OP specified that the file was executable, which is required for `path/to/script.sh`, but not for `sh script.sh`.
Chris Johnsen
A: 

Hi Ritesh

sh script.sh forces the script to be executed within the sh - shell.

while simply starting it from command line uses the shell-environemnt you're in.

Please post the error message for further answers.

Random though on what the error may be: path specified in first line /bin/bash is wrong -- maybe bash is not installed?

Markus Maria Miedaner
It is up to the kernel to decide what to do with a script run as `./script.sh`. In nearly all situations, if the first line is a hash-bang line, the kernel will start the interpreter named on that line with the script's pathname as its next argument (after any options supplied on the hash-bang line). You can be running any shell (*zsh*, *dash*, *ksh*, *fish*, *tcsh*, etc.) and `path/to/script.sh` will use the interpreter specified in the hash-bang line.
Chris Johnsen
+1  A: 

if your script is at your present working directory and you issue ./script.sh, the kernel will read the shebang (first line) and execute the shell interpreter that is defined. you can also call your script.sh by specifying the path of the interpreter eg

/bin/bash myscript.sh
/bin/sh myscript.sh  
/bin/ksh myscript.sh etc 

By the way, you can also put your shebang like this (if you don't want to specify full path)

#!/usr/bin/env sh
ghostdog74
Actually the kernel is who interprets the shebang, not the shell.