209

I wanted to execute a shell script:

-rwxr-x--x 1 root root   17234 Jun  6 18:31 create_mgw_3shelf_6xIPNI1P.sh

I tried to do a standard procedure, but I got this error:

./create_mgw_3shelf_6xIPNI1P.sh 
localhost 389 -l /opt/fews/sessions/AMGWM19/log/2013-06-06-143637_CLA-0 
DEBUG   cd/etc/opt/ldapfiles/ldif_in ;
./create_mgw_3shelf_6xIPNI1P.sh 
localhost 389 -l /opt/fews/sessions/AMGWM19/log/2013-06-06-143637_CLA-0
**ERROR  sh: ./create_mgw_3shelf_6xIPNI1P.sh: /bin/bash^M: bad interpreter: No such file or directory**

What does it mean? I was doing this as the root user under the root group.

Does it mean that the file does not have the correct permission for the root user?

edwinksl
  • 23,789
user165062
  • 2,153
  • 3
  • 14
  • 6

8 Answers8

354

This isn't a permission issue, you aren't getting a message about permissions

/bin/bash^M: bad interpreter: No such file or directory

The script indicates that it must be executed by a shell located at /bin/bash^M. There is no such file: it's called /bin/bash.

The ^M is a carriage return character. Linux uses the line feed character to mark the end of a line, whereas Windows uses the two-character sequence CR LF. Your file has Windows line endings, which is confusing Linux.

Remove the spurious CR characters. You can do it with the following command:

sed -i -e 's/\r$//' create_mgw_3shelf_6xIPNI1P.sh
  • 32
    Or install and use the dos2unix program. – argentpepper Jun 06 '13 at 22:56
  • 5
    thank you for this, all other answers Ive found so far have not helped. This one did it! – qodeninja Jun 09 '14 at 23:39
  • doesn't have to be Windows, I got a similar message after copying a script from OS X to Ubuntu... dos2unix worked great in that case, whereas replacing '\r' with nothing would be worse, since there are no '\n' characters in the file. – Michael Sep 14 '16 at 17:39
  • 1
    @Michael macOS uses \n because it's Unix. The script was maybe from an earlier Mac OS version? You could run sed -i -e 's/\r$/\n/' script.sh in that case. – wjandrea Dec 21 '16 at 04:49
  • 2
    Open it in gedit and, do Save As, and select "Line Ending: Unix/Linux" – Mattmon Nov 27 '17 at 12:11
  • Thanks a lot bro. This really saved my time...! – BharathRao Oct 17 '18 at 14:21
  • In SciTE editor, to display characters:"View""End of Line" . To change the End of line character "Options","Line End Characters", then choose "LF". Now you can replace all the wrong "CR" by "LF" using "Options""Convert Line End Characters" – Daniel Perez Feb 27 '20 at 14:58
  • You can use the button on the bottom right in VS-Code to switch between CRLF (windows, dos) and LF (unix). – Andreas L. Sep 09 '21 at 11:37
  • Just to share, this command works fine in Linux - In MacOS (El Capitan) does not work - practically all remain without the expected change – Manuel Jordan Dec 18 '21 at 13:19
  • 1
    @ManuelJordan This is Ask Ubuntu, so I gave a command that works on Ubuntu, and more generally on Linux (including BusyBox). On other Unix-like systems you can use (for example) perl -i -pe 's/\r$//' … . On systems that don't recognize \r to mean a carriage return, the command I posted might error out of might remove r or \r (the two-character sequence backslash, lowercase R) at the end of lines. Recent macOS (at least Big Sur) does interpret \r as CR though. – Gilles 'SO- stop being evil' Dec 19 '21 at 11:55
  • @Gilles'SO-stopbeingevil' - it was just an observation. Thanks for your understanding. – Manuel Jordan Dec 19 '21 at 12:37
49

In vim you could also use :set ff=unix and then save the file, or :set ff=dos to get DOS formatting again.

ortang
  • 2,143
  • 14
  • 13
45

Your file has DOS/Windows style line endings (CR LF), but on Unix-like systems only the LF control character is used as line break.

The additional CR control character is shown encoded as ^M in your output. You can also see it when you run cat -A create_mgw_3shelf_6xIPNI1P.sh.

To convert the line endings from DOS/Windows style to Unix style, there's a tool called dos2unix. You install it using:

sudo apt-get install dos2unix

Then you can simply convert files' line endings in both ways using

dos2unix FILENAME
unix2dos FILENAME

In your case, simply run this command below and the script file will be converted in-place:

dos2unix create_mgw_3shelf_6xIPNI1P.sh

After that Bash should be able to interpret the file correctly.

Byte Commander
  • 107,489
18

The Problem ist you edit with Dos!

open your file with vi then set unix with:

:set ff=unix
:wq

and it all fine

muru
  • 197,895
  • 55
  • 485
  • 740
DaFreder
  • 181
6

As explained in the other answers, this is a format issue. So, the answer is to change the format from DOS to Unix style line endings. This is yet another simple way to fix your file 'in place'

fromdos file

It's available in package tofrodos:

sudo apt-get install tofrodos
Byte Commander
  • 107,489
josediazaz
  • 61
  • 1
5

Do vi <your script>.

then :set list; it will display any of the special characters in your script.

then replace the character:

:%s/^M//gc [to type ^M press Ctrl + v + m]

strugee
  • 1,092
  • See above answer about using :fileformat which is IMHO better for handling this than global substitution Also, see https://stackoverflow.com/questions/14609779/how-can-i-configure-bash-to-handle-crlf-shell-scripts/14610541 for ideas on how to handle automatically – qneill Aug 11 '17 at 15:58
  • I did :set list but say no special characters. Just a $ at the end of every line. – RonJohn Jan 16 '22 at 05:30
4

You can also use gedit to remove the unwanted characters. Under the File menu select Save As and set the line end type unix/Linux.

Seth
  • 58,122
tphistry
  • 41
  • 1
0

I had developed the bash script on a Mac, so the first line of the script was

#!/opt/homebrew/bin/bash

When I tried to run it on ubuntu, I got the bad-interpreter issue. I changed the first line to

/usr/bin/bash

This change worked on ubuntu which bash command on ubuntu to find the path of bash.

Siddharth
  • 331