views:

70

answers:

6

I'm learning how to make shell scripts in UNIX, but I keep coming across this stupid error. Let's say I make a script like this:

#!/bin/sh
echo HELLO

I save the file as test, and make the command executable by me with chmod 700 test. I save the file in my home directory, and (attempt) to run the file like so:

./test

Only for UNIX to reply back:

./test: Command not found.

What is going on? When I type out ls -l, there is an asterisk next to the file name. That wasn't there before I used the chmod command. Can anyone tell me what I'm doing wrong?

+3  A: 

It looks like you need a slash before the bin:

#!/bin/sh
# ^

Everything else looks fine... I'm assuming that /bin/sh is the location of your executable Bournse shell - if it is not, you would need to adjust as appropriate. Without the leading slash your shell is looking for bin/sh relative to your current directory, rather than where it truly resides.

You'll need to locate the executable shell interpreter that you want (or need) for your scripts.

A couple more suggestions - on my machine I get these results:

# tells you where sh resides, if it is on your path
$ which sh
/bin/sh

# tells you which shell you are currently using
$ echo $SHELL
/bin/tcsh

I can use either of these for the 'shebang' line in a simple shell script. You may find that your Bourne shell is located in /usr/bin rather than /bin for example.

martin clayton
Well, I just replaced the header with what you posted, and I'm getting the same error.
Waffles
A: 

The #! tells Unix to execute your script using the program specified. In your case you've specified bin/sh, but it should be /bin/sh. The error message that Unix gives isn't particularly clear as to which program it can't find.

Brian Agnew
A: 

Make it executable:

chmod +x ./test

and make sure you save your file in unix file format

ivy
A: 

To add to Martin's answer, you say that you save the file in your home directory and run it as ./test. This will work only if your current working directory is the same as your home directory.

The asterisk next to the file name means that file is executable.

Vlad Lazarenko
Well, I am currently in my home directory.
Waffles
@Waffles: If Martin's answer didn't help and you are in the same directory where file is located... are you sure that you have `/bin/sh` program? It might be `/bin/zsh` or '/bin/bash` depending on what exactly UNIX-like system you are running.
Vlad Lazarenko
Anything that can reasonably be called unix has a Bourne or POSIX shell as `/bin/sh`, even if the preferred shell is something else like `/bin/bash` or `/bin/ksh`.
Gilles
@Gilles: Well unless you mess up with the system badly, which Waffles can do looking at his question :)
Vlad Lazarenko
A: 

When ./test is an executable script and yet executing it gives the error message ./test: Command not found, check that the interpreter exists. You must give an absolute path (the PATH environment variable is not used).

If the file has gone through a Windows machine, make sure there isn't a spurious carriage return at the end of the line, as CR would be part of the interpreter file name. You can check with <test head -n 1 | od -t x1: if this ends with 0d 0a, there is a CR and you need to remove it (you may need to remove CR from other lines as well).

Gilles
A: 

This is very strange indeed. The steps you describe should have worked, so there must be some small error in your environment or the execution of those steps. There are some things you can do to help diagnose this:

CHECKING FOR CONTROL CHARACTERS

What you've documented looks fine, as long as there are no typos or control characters. You should check by typing:

cat -vt ./test

If you see any unexpected extra text that could explain the problem. For example, "^M" at the end of a line would indicate that your editor saved the file in Windows format.

REGENERATING THE FILE RELIABLY

To create a known-good ./test2, copy-paste the commands below:

`which bash`
printf "#\!`which sh`\necho HELLO\n" > ./test2
chmod +x ./test2
./test2
exit

CHECKING WHICH COMMAND CAN NOT BE FOUND

If you type...

./ajio

...do you get exactly...

./ajio: Command not found.  

...as you described with ./test? I just made up the name ajio so it shouldn't exist. If they messages match then it doesn't really tell you anything new. But if the messages differ, that confirms that ./test was at least found and executable.

It's also possible that your version of sh is trying to tell you not that test can't be found, but that while running test some command the shell tried to run couldn't be found. That shouldn't be the echo command, as with most shell implementations that will be an internal command, implemented inside the shell. But, the shell may run an initialisation script containing a line specifying a command it can't run. If you run man sh, it will tell you about all the different startup files that your shell might try to run. These can be different from those used when you start the shell interactively. But, as a beginner, it can be daunting checking the validity of those scripts. It's likely that any bogus customisations would be to your personal shell startup process though, and not afflicting the entire Linux install, so run ls -ld ~/.* to list the hidden files in your home directory, and inspect any that look like shell startup files (e.g. ~/.bashrc, ~/.profile, ~/.bash_login). Check any commands they specify can be found with which, and are invoked after the path variable is set to include their location.

COMPARING TO ANOTHER SHELL

If there's a problem with the /bin/sh install / initialisation, then you might be able to bypass it by invoking another shell. Try...

which zsh
which tcsh
which csh

...and if one of more of these finds an alternative shell for you, edit or recreate the file specifying that shell, ala...

#!/bin/csh
echo HELLO

...then chmod +x it and ./-run it. If that works, then you know your problem is /bin/sh specific.

Tony