-4

Why doesn't Ubuntu support sh example.sh command?

It's more convenient than cd $wd; ./example.sh and add PATH in some situation.

login.sh:

~/bin/logmitgw.sh -i 4564646 dfdsfsdf

logmitgw.sh:

some code

When I'm running sh ~/bin/login.sh

I get:

sh: 0: Can't open ~/bin/login.sh

ls -l ~/bin/login.sh outputs -rwxrwxr-x

5
  • 1
    What is cd $wd?
    – Kevin
    Nov 18, 2012 at 4:13
  • change working directory to the shell directory
    – qingfeng
    Nov 18, 2012 at 4:17
  • 3
    You need to be more specific about your problem. The example you gave (sh example.sh) should work, unless the script you are trying to execute requires another shell or interpreter different from sh.
    – Salem
    Nov 18, 2012 at 4:21
  • @Salem I have edited my question.
    – qingfeng
    Nov 18, 2012 at 4:29
  • You didn't actually answer the first question... what is cd $wd? This could only work if you have something like wd=~/bin defined elsewhere, but why? Nov 18, 2012 at 6:07

2 Answers 2

2

Ubuntu does support running sh example.sh. That works fine if you do everything else right. The problem in your case seems to be that you are giving the incorrect path to the script.


When you open a terminal in Ubuntu, it most likely starts a Bash shell. I will assume that to be the case for you.

Also, the command sh calls a different shell:

$ command -v sh
/usr/bin/sh
$ ls -l /usr/bin/sh
lrwxrwxrwx 1 root root 13 Aug  4 11:43 /usr/bin/sh -> /usr/bin/dash

That is, /usr/bin/sh is a symlink to the dash shell. On some systems, the sh symlink may be to another shell.

One thing that might go wrong, is that there is no sh in the system.

Here is an example script:

$ echo 'echo "works!"' > ~/bin/example.sh
$ sh ~/bin/example.sh
works!

If I delete the sh symlink, I get an error:

$ sudo rm /usr/bin/sh
$ sh ~/bin/example.sh
bash: /usr/bin/sh: No such file or directory

Note that this is not the error you got.

I ran sudo ln -s /usr/bin/dash /usr/bin/sh to make the symlink again and get my sh back.

Another problem could be that the file is not a shell script, and dash is not able to run it, or it is a shell script, but it is not compatible with dash. In that case, you will get a syntax error of some kind, for example:

$ file /bin/bash
/bin/bash: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=a6cb40078351e05121d46daa768e271846d5cc54, for GNU/Linux 3.2.0, stripped
$ sh /bin/bash
/bin/bash: 1: ELF: not found
/bin/bash: 2: Syntax error: Unterminated quoted string
$ file /usr/bin/uname
/usr/bin/uname: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=3354931bca4ff072b26258a956ffde08ead5f341, for GNU/Linux 3.2.0, stripped
$ sh /usr/bin/uname
/usr/bin/uname: 1: Syntax error: word unexpected (expecting ")")

But you did not get an error like that.

When the dash shell is asked to run a file that does not exist, it outputs the error you show in your question:

$ ls ~/bin/anything
ls: cannot access '/home/zanna/bin/anything': No such file or directory
$ sh ~/bin/anything
sh: 0: Can't open /home/zanna/bin/anything

The 0 in this error is the current file:

$ echo 'echo $0' > ~/bin/something
$ sh ~/bin/something
/home/zanna/bin/something

In your question, you say that you ran

sh ~/bin/login.sh

and got

sh: 0: Can't open ~/bin/login.sh

But that error does not make sense, because the tilde ~ should be expanded to the path of your home directory. Remember my error:

$ sh ~/bin/anything
sh: 0: Can't open /home/zanna/bin/anything
                     ^___^------expansion of ~    

I can reproduce your error by quoting the path:

$ sh ~/bin/example.sh 
works!
$ sh "~/bin/example.sh" 
sh: 0: Can't open ~/bin/example.sh

Maybe that is what you did.

Or, looking at the revision history of your post, it seems you may have run

sh /bin/login.sh

That does not work, and will output sh: 0: Can't open /bin/login.sh unless there is a file login.sh in the top level directory /bin. You would probably know if you had created such a file, because you would have had to do so as root.

Another reason why you would get the error sh: 0: Can't open /path/to/file, is that you ran sh ~/bin/login.sh but there was no such file. But, the ~ would still have been expanded in that case. Also, you give the first part of the output of ls -l for your file, to show the permissions:

-rwxrwxr-x

So, apparently, ~/bin/login.sh is a regular file with permissions 775. So perhaps that was not the problem.

Note that, when you call an interpreter, such as (da)sh, to run a script, the script need not have execute permission:

$ ls -l ~/bin/example.sh
-rw-rw-r-- 1 zanna zanna 14 Aug  4 11:36 /home/zanna/bin/example.sh
$ sh ~/bin/example.sh 
works!

But your script calls another script, without calling an interpreter to run it. That would cause a permission error if the second script had no execute permission:

$ echo '~/bin/example.sh' > ~/bin/something
$ sh ~/bin/something
/home/zanna/bin/something: 1: /home/zanna/bin/example.sh: Permission denied

But, once again, this is not the error you got.

You accepted the answer by fabricator4, which pointed out that ~/bin is added to PATH if it exists (you can see the code that does this in ~/.profile), so if you have an executable in ~/bin, you can run it without specifying the interpreter, but for that to work, the file must have execute permission:

$ example.sh
bash: /home/zanna/bin/example.sh: Permission denied
$ chmod u+x ~/bin/example.sh
$ example.sh
works!

(Here though the current shell, which we are assuming is Bash, and probably not dash, executes the script, in the absence of any interpreter directive)

Since that answer worked for you, then it seems that the file existed, it had execute permission, and was a script compatible with Bash. What went wrong with your attempt to run it with the syntax sh example.sh then, seems to have been that you either quoted the path and prevented tilde expansion, or omitted the ~ entirely, thus, in either case, specifying the wrong path to your file.

1

If the script is in ~/bin then ~/bin will already be in the path. As long as it's a bash script you can execute it from anywhere at all. No need to shell, no need to cd, and no need to add anything in your path.

eg:

login.sh

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .