When I want to run
.sh files in Terminal, I need to put
sh in front of them.
Is there any way to avoid this, and thus save typing?
If you're running your script from the shell, you don't actually need the
#!/bin/sh shebang as outlined in this this answer–every Unix-like system I've used, including OS X, will default to
/bin/sh if no interpreter is specifically specified (though it's a good idea as non-shells won't know how to execute your script unless you give the shebang.)
You also don't need an
.sh extension. You do need to set executable permissions, e.g.
$ chmod +x script.sh
$ is the shell prompt; I'm using it to illustrate commands you give to the interactive shell. Don't type it!)
However, I think what your confusion is is that you have created a script, e.g.
script.sh, in the current directory, and are trying to execute it by simply typing
$ cat >script.sh echo hello, world ^D $ chmod +x script.sh $ script.sh -bash: script.sh: command not found
^D means control-D. You will find this notation in many writeups on using Unix.)
The fact that
script.sh in this case is a shell script is only half the problem; your actual issue is that, by default, the shell will not search the current directory for a program. However, this works:
$ sh script.sh hello, world
sh is taking the script as an argument.
You can execute a script–or, again, any executable–in the current directory, if it is marked executable (i.e.
chmod +x), by specifying that you want to run the one in the current directory:
$ ./script.sh hello, world
You can also move the script to a directory on your
PATH. I recommend
/usr/local/bin for this if your script is intended to be used system-wide, or a
bin directory in your home if the script is only for you. The latter requires you to add
$HOME/bin, which expands to your new bin directory, to your
PATH by adding the following lines to your
.profile in your home directory:
PATH=$HOME/bin:$PATH export PATH
Finally, you can, if you want, actually add the current directory to your
PATH, which will allow you to just go to a directory containing
script.sh–or any other executable–and type
to execute it. However, I do not recommend this practice, as an attacker can now trick you into running an arbitrary executable by dropping an executable script (named, say,
ls) into a directory you will be in. If you really want to do it, though, just add the following to your
PATH=.:$PATH export PATH
You don't need to call
sh if the script file is marked as executable. In that case, you can call it my name just like you would any other command from the existing shell.
To be fully proper, you'll want to do two things:
Edit your script to include a shebang directive at the top of your script:
... That would tell the shell which interpreter to use to run the script; in this case, the
Mark the script as executable by you with the chmod command:
chmod u+x scriptname.sh
Once you do both of those, you should be able to run your script by typing your script's file name on the command line. You'll need to be in the same directory as your script, unless you also take the added step of adding the containing folder to your PATH variable. If you don't care what shell runs the script, you don't need step one to specify
sh but it's often better to be precise and set the "shebangsh".