Bash - seamlessly run scripts with CRLF line endin

2019-03-25 05:48发布

I am using VM (in my case simply boot2docker) to run docker containers on Windows host. For convinience, my source files are mapped from host file system, so text files are by default using Windows-style CRLF line endings instead of Unix-style LF endings.

When I try to run some .sh file from docker container, I'll get an error

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

Is there a way how could I somehow tell bash/sh interpreter to automatically convert \r\n to \n and run a file?

Sure, I could do some piplelining like this cat script.sh | tr -d "\r" | sh or even create an alias for that, but it would not cover situation where one script includes another.

The only acceptable solution I have found so far, is to set Git to checkout source files in UNIX format.

4条回答
贪生不怕死
2楼-- · 2019-03-25 06:03

You can commit a .gitattributes file in your repo in the root folder to automatically tell Git to apply LF line endings to all .sh files when checking out, even on Windows. This way you or other developers don't have to remember to configure Git on each machine where you clone your repo.

# Set line endings to LF, even on Windows. Otherwise, execution within Docker fails.
# See https://help.github.com/articles/dealing-with-line-endings/
*.sh text eol=lf
查看更多
看我几分像从前
3楼-- · 2019-03-25 06:04

I imagine you could write a script such as

#!/bin/bash
#bash_run_unixified
#unixify and run in bash
dos2unix < "$1" | /bin/bash

and assuming you saved it in /urs/local/bin/bash_run_unixified with appropriate permissions (sudo chmod o+r,o+x), then you could prefix your scripts with

#!/usr/local/bin/bash_run_unixified
#This script has CRLFs in it

If you don't want such unusual shebang lines, you could

$ ln -s /usr/local/bin/{bash_run_unixified,bash}

and then use (As Walter A. notes, it might be a good idea to link it to bash^M too)

#!/usr/bin/env bash

as your shebang line (/usr/local/bin/ is normally closer to the beginning of your $PATH than /bin so the env command should select the bash that links to bash_run_unixified).

(Word of caution: I haven't tested any of this)

查看更多
倾城 Initia
4楼-- · 2019-03-25 06:11

The best solution I have is to make sure to use editors (like Notepad++ or Sublime Text) able to save directly with the proper eol style.

That way, I don't have to dos2unix any file in my boot2docker session.

查看更多
爱情/是我丢掉的垃圾
5楼-- · 2019-03-25 06:21

For some scripts the solution ln -s /bin/bash /bin/bash^M will fail.
So create a script /bin/bash^M that will dos2unix the arguments they get and run them with "$@".

Edit: I tried it with the following bash^M script:

#!/bin/bash
PROG=$1
shift
dos2unix $PROG > /dev/null 2>&1
$PROG "$@"

This will fail when your script includes other scripts with a dot, in that case you should avoid this work-around and go for the Unix format.
You said you can checkout in Unix format, or you can self change the files.
And commit into git, it is an improvement to have unix files stored in git in unix format. When you really want to edit them under windows, change the settings of your editor or dos2unix afterwards.

查看更多
登录 后发表回答