745

I'm using this tutorial to learn bash scripts to automate a few tasks for me.
I'm connecting to a server using putty.

The script, located in .../Documents/LOG, is:

#!/bin/bash
# My first script
echo "Hello World!"

And I executed the following for read/write/execute permissions

chmod 755 my_script

Then, when I enter ./my_script, I'm getting the error given in the title.

Some similar questions wanted to see these, so I think they might help :

$ which bash
/bin/bash

and

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/bin/mh

I tried adding the current directory to PATH, but that doesn't work …

Henke
  • 4,445
  • 3
  • 31
  • 44
cartonn
  • 7,654
  • 3
  • 19
  • 19
  • How did you create the file? E.g. Which editor / OS – cowls Jan 08 '13 at 16:05
  • I created the file in Windows using Notepad++, copied the file over to the server using WinSCP. And I know this isn't the ideal way to do things – cartonn Jan 08 '13 at 16:07
  • 1
    See my answer, this is most likely the issue – cowls Jan 08 '13 at 16:08
  • I got this with a hashbang misspelling: ``#! /user/bin/env python``. note ``user`` instead of ``usr``, so check your ``env`` top-line statement – kmiklas Jul 24 '20 at 13:36
  • 16
    I voted to reopen this question because the title contained `/bin/bash^M: bad interpreter: No such file or directory`, which led me from a Google search directly to a solution. The "duplicate" question did not. – Jim Tough Jan 11 '21 at 22:51
  • FYI - I had this problem when duplicating a `.bat` file and changed the extension to `.sh`. My plan was to rewrite the batch code to shell. Creating a new `.sh` file and pasting my code over did the trick. – drake7 Apr 02 '21 at 15:53
  • I had this problem when working with WSL2 and running Docker backend at the same time. Shutting down Docker and doing `wsl --shutdown`, then starting it again fixed the issue. – Nicolás de Ory Apr 14 '21 at 10:15

11 Answers11

1170

The reason might be that you saved the file on Windows, with CR LF as the line ending (\r\n).

Run the following command in your terminal:

sed -i -e 's/\r$//' scriptname.sh

(Of course, change scriptname.sh to your file name)

The command will replace those CR characters with nothing, which will leave these lines with LF (\n) as the ending, and Bash will be able to read and execute the file by running

./scriptname.sh
Nivin V Joseph
  • 12,042
  • 2
  • 15
  • 24
  • 7
    If this not worked, try `sed -i -e 's/^M$//' scriptname.sh`. (Press Ctrl+V Ctrl+M to insert that `^M`.) – youhans Jul 16 '17 at 20:20
  • 3
    This didn't work for me, including the . However, the original answer had a solution that did work for me: open the file in Vim and run the following command before saving: :set fileformat=unix listed under the SO question called Are shell scripts sensitive to encoding and line endings? did work for me. – Jazzmine Jan 15 '18 at 16:10
  • 2
    bonus for working on docker containers that don't have dos2unix installed. Though I couldn't overwrite the script in my case so mine looked like `cat scriptname.sh | sed -e 's/\r$//' > fixedscriptname.sh` – Rhubarb Feb 20 '19 at 11:10
  • 2
    If it helps, I used sed -i -e 's/\r$//' *.sh which converted all my sh files to make them work – Mark N Hopgood May 07 '19 at 14:27
  • None of the answers here worked except @Jazzmine `:set fileformat=unix` in `vi`. I have the feeling Linux/Nano was actually changing my file's LF into CRLF for some reason. – Marc Nov 08 '19 at 14:31
  • 30
    @Robert Molina, windows adds a carriage return character in addition to \n at the end of lines. This command simply removes it by substituting \r for an empty string using the linux stream edit command (sed). – Michael Szczepaniak Sep 02 '20 at 16:59
  • 2
    WHAT this answer explain is that you are not using UNIX end lines. Check accepted answer. If you are working in Windows, for e.g. Notepad++, check for Edit / Convert End Lines / Unix format. – Leandro Bardelli May 06 '22 at 15:10
  • Works within debian linux. – raz Jul 24 '23 at 09:20
836

I have seen this issue when creating scripts in Windows env and then porting over to run on a Unix environment.

Try running dos2unix on the script:

http://dos2unix.sourceforge.net/

Or just rewrite the script in your Unix env using vi and test.

Unix uses different line endings so can't read the file you created on Windows. Hence it is seeing ^M as an illegal character.

If you want to write a file on Windows and then port over, make sure your editor is set to create files in UNIX format.

In notepad++ in the bottom right of the screen, it tells you the document format. By default, it will say Dos\Windows. To change it go to

  • settings->preferences
  • new document / default directory tab
  • select the format as unix and close
  • create a new document
cowls
  • 24,013
  • 8
  • 48
  • 78
  • 43
    You can also just right click on the Dos\Windows text in the bottom right and change it to unix there. – Hardy Nov 19 '15 at 19:00
  • 4
    +1 for such an unlikely solution!! I am using UltraEdit. To achieve the same there, select File -> Conversions -> DOS to Unix – imnd_neel May 11 '16 at 12:05
  • I open the script in notepad and paste into putty shell , then save it. Everything fine for now. Thank you for your answer. – Dylan B Feb 22 '17 at 02:52
  • I faced same issue. I had written the script in windows env and copied onto linux machine. The error gone after rewriting the script in linux machine itself – shaiksha Aug 10 '17 at 16:52
  • 7
    If you use Sublime Text 3 editor, you can convert line endings from Windows to Linux format by selecting `View->Line Endings->Unix` and then save your script with `Ctrl+S` – Alfredo Capobianchi Aug 17 '17 at 21:53
  • Very simply, just use gedit and do a `Save As...` and change the line endings to `Unix/Linux`. – Chef Pharaoh Nov 20 '17 at 17:34
  • Changing the settings in Notepad++ is **so much** easier than relearning vi after so many years! :-) – DRosenfeld Sep 06 '18 at 08:42
  • Or you can also type the following command in your file in VIM : set ff=unix – Frederic Jan 02 '19 at 03:21
  • 5
    Under VSCode you can change the Linefeed option on the bottom right from CRLF to LF to achieve the same as in this post. – Snapstromegon Jul 24 '19 at 07:07
  • So I have a zip file I created on a mac. I had downloaded and rezipped it on a windows machine. (dont ask). Then I unzipped to a ubuntu machine...and got the error. But this answer got me on the right track. – granadaCoder Jun 10 '20 at 22:03
  • Depending on how git's line ending management is configured this can become an automatically created problem on every script in a project. – geneorama Jul 08 '20 at 14:36
  • If you consistently have issues like this then [you can symlink /path/to/interpreter^M to /path/to/interpreter](https://natanyellin.com/posts/shebang-python-bad-interpreter-m/) to avoid constantly converting line endings. It's ugly but it works. – Natan Yellin Nov 22 '20 at 19:36
  • I got `dos2unix: Failed to open temporary output file: Permission denied; dos2unix: problems converting file /mnt/c/Program Files/nodejs/npm` – Timo Mar 10 '21 at 06:52
161

If you use Sublime Text on Windows or Mac to edit your scripts:

Click on View > Line Endings > Unix and save the file again.

enter image description here

fivestones
  • 119
  • 2
  • 12
Mario Campa
  • 4,092
  • 1
  • 26
  • 25
73

In notepad++ you can set it for the file specifically by pressing

Edit --> EOL Conversion --> UNIX/OSX Format

enter image description here

Urik
  • 1,598
  • 3
  • 19
  • 37
60

This is caused by editing file in windows and importing and executing in unix.

dos2unix -k -o filename should do the trick.

StonecoldIM
  • 654
  • 1
  • 6
  • 6
20

problem is with dos line ending. Following will convert it for unix

dos2unix file_name

NB: you may need to install dos2unix first with yum install dos2unix

another way to do it is using sed command to search and replace the dos line ending characters to unix format:

$sed -i -e 's/\r$//' your_script.sh
Md. Shafiqur Rahman
  • 2,878
  • 27
  • 24
18

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$//' setup.sh
kalyani chaudhari
  • 7,515
  • 3
  • 24
  • 21
9

I was able to resolve the issue by opening the script in gedit and saving it with the proper Line Ending option:

File > Save As...

In the bottom left of the Save As prompt, there are drop-down menus for Character Encoding and Line Ending. Change the Line Ending from Windows to Unix/Linux then Save.

Selecting the "Line Ending" option as "Linux/Unix" in the gedit "Save As" prompt

NWRichmond
  • 311
  • 3
  • 6
8

For Eclipse users, you can either change the file encoding directly from the menu File > Convert Line Delimiters To > Unix (LF, \n, 0Α, ¶):

Eclipse change file encoding

Or change the New text file line delimiter to Other: Unix on Window > Preferences > General > Workspace panel:

Eclipse workspace settings

Christos Lytras
  • 36,310
  • 4
  • 80
  • 113
  • _File > Convert Line Delimiters To_ does it but _Window > Preferences > General > Workspace > Unix_ does not seem to help. – Panu Haaramo Nov 13 '17 at 12:17
  • 1
    @PanuHaaramo that setting is for all **NEW** created files. If you have a file that it's created already, then you have to convert it as in the first screenshot. – Christos Lytras Nov 13 '17 at 14:35
1

Atom has a built-in line ending selector package

More details here: https://github.com/atom/line-ending-selector

tuanh118
  • 311
  • 2
  • 5
0

I develop on Windows and Mac/Linux at the same time and I avoid this ^M-error by simply running my scripts as I do in Windows:

$ php ./my_script

No need to change line endings.

MrMacvos
  • 103
  • 2
  • 8