Making bash run DOS/Windows CRLF EOL scripts

If you for any reason use a Windows editor to write scripts, it can be annoying to remember to convert them and bash fails in mysterious ways when you don’t. Let’s just get rid of that problem once and for all:

cat > $'/bin/bash\r' << "EOF"
#!/usr/bin/env bash
exec bash <(tr -d '\r' < "$script") "$@"

This allows you to execute scripts with DOS/Windows \r\n line endings with ./yourscript (but it will fail if the script specifies parameters on the shebang, or if you run it with bash yourscript). It works because from a UNIX point of view, DOS/Windows files specify the interpretter as "bash^M", and we override that to clean the script and run bash on the result.

Of course, you can also replace the helpful exec bash part with echo "Run dos2unix on your file!" >&2 if you'd rather give your users a helpful reminder rather than compatibility or a crazy error.

5 thoughts on “Making bash run DOS/Windows CRLF EOL scripts”

  1. /bin/bash is bogus because it rarely exists. /usr/bin/env bash is better; /bin/sh is best as it is portable. If you must use an absolute path use /usr/local/bin/bash

  2. Fair enough (though /bin/sh isn’t portable for running bash specific scripts). I’ve updated it.

    I kept bash^M in /bin though, as /bin/bash is much more common than /usr/local/bin/bash on Linux (the explicit scope of this post). It will still work if the DOS script specifies “/usr/bin/env bash”.

  3. Ooook. And where does your code go? Into another script, which you executie? Because I tried that, passed it the DOS-formatted script name, and got \Permission denied in/bash\

  4. @terry
    You just run it as root, and it creates a file called /bin/bash$'\r'. Then chmod a+x /bin/bash$'\r'.

    Afterwards, any DOS formatted bash scripts you chmod a+x file and run with ./file should just automagically work as if they were Unix formatted.

Leave a Reply