6

I have two similar scripts with different names. One works fine but other throws error. Can anyone please tell me what is the issue?

This is my test.sh scripts which works fine

[nnice@myhost Scripts]$ cat test.sh 
#!/bin/bash
function fun {     
        echo "`hostname`"
}
fun 
[nnice@myhost Scripts]$ ./test.sh 
myhost.fedora

Here is my another script demo.sh but it throws error

[nnice@myhost Scripts]$ cat demo.sh 
#!/bin/bash
function fun { 
    echo "`hostname`"
}
fun
[nnice@myhost Scripts]$ ./demo.sh 
bash: ./demo.sh: cannot execute: required file not found

Both scripts having the same permissions

[nnice@myhost Scripts]$ ll test.sh 
-rwxr-xr-x. 1 nnice nnice 65 Oct 21 10:47 test.sh
[nnice@myhost Scripts]$ ll demo.sh 
-rwxr-xr-x. 1 nnice nnice 58 Oct 21 10:46 demo.sh
4
  • Note: use of back ticks e.g. ... `command` ... is deprecated. Use the newer easier to use "$(command)" (but yes this simple use with echo is hoop jumping). Use of .sh at the end of file names is not Unix. And it violates the principle of abstraction, as it leaks implementation detail. Just name them by what they do, not how they do it. Oct 21, 2022 at 8:16
  • @ctrl-alt-delor They are most definitely not deprecated, only awkward to use and should be avoided. In this particular case, any type of command substitution would be inappropriate. As for naming files, that's really up to the user. If you are concerned with abstraction, you could suggest the user uses the hostname command directly rather than via a nonsensical script with a function.
    – Kusalananda
    Oct 21, 2022 at 8:22
  • deprecate : express disapproval of. I disapprove. You say should be avoided. Thus deprecated. As for up to the user. I agree, it is the same for drug use. And the best abstraction is no abstraction (it depends). However I assume the examples were minimum non-working examples. Oct 21, 2022 at 8:29
  • fwiw, this error is usually a bad shebang, see also stackoverflow.com/a/18818809/127971
    – michael
    Jan 7 at 3:48

3 Answers 3

16

Your demo.sh script is a DOS text file. Such files have CRLF line endings, and that extra CR (carriage-return) character at the end of the line is causing you issues.

The specific issue it's causing is that the interpreter pathname on the #!-line now refers to something called /bin/bash\r (with the \r symbolising a carriage-return, which is a space-like character, so it's usually not visible). This file is not found, so this is what causes your error message.

To solve this, convert your script from a DOS text file to a Unix text file. If you are editing scripts on Windows, you can probably do this by configuring the Windows text editor to create Unix text files, but you may also use the dos2unix utility, available for most common Unix variants.

$ ./script
bash: ./script: cannot execute: required file not found
$ dos2unix script
$ ./script
harpo.local

Regarding your code: Please never do echo `some-command` or echo $(some-command) to output the output of some-command. Just use the command directly:

#!/bin/sh

fun () {
    hostname
}

fun

(Since the script now does not use anything requiring bash, I also shifted to calling the simpler /bin/sh shell.)

0
0

(Because my search ended up here), I had test.sh

#!/bin/bash
echo "test"

that I copied to NixOS and got

-bash: ./test.sh: cannot execute: required file not found

I tried my default vim method of removing windows carriage-returns:

:e ++ff=unix 
:%s/\r\(\n\)/\1/g

but that didn't help.

I changed the first line to

#!/usr/bin/env bash

and it now works.

I could have changed it to

#!/bin/sh

as I wasn't using any bashism but in another script I was so I needed a nice portable way to invoke bash.

-2

In my instance, on Windows, this was caused by the bash script I was trying to execute using this shebang #! /user/bin/bash instead of #!/bin/bash.

You must log in to answer this question.

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