Keywords: line endings | Git configuration | bash error | core.autocrlf | cross-platform compatibility
Abstract: This article provides a comprehensive analysis of the env: bash\r: No such file or directory error encountered when executing scripts in Unix/Linux systems. Through detailed exploration of line ending differences between Windows and Unix systems, Git's core.autocrlf configuration mechanism, and technical aspects like ANSI-C quoted strings, it offers a complete solution workflow from quick fixes to root cause resolution. The article combines specific cases to explain how to identify and convert CRLF line endings, along with Git configuration recommendations to prevent such issues.
Problem Phenomenon and Error Analysis
During script execution for installation purposes, users encounter the env: bash\r: No such file or directory error message. The core issue lies in the script file containing incompatible line ending formats. In Unix/Linux systems, line endings should consist of a single newline character \n, while the bash\r in the error message indicates the script file contains Windows-style \r\n line endings.
Technical Background of Line Ending Differences
Different operating systems employ distinct line ending standards: Unix/Linux systems use \n (LF), Windows systems use \r\n (CRLF), and classic Mac systems use \r (CR). This divergence stems from historical development but frequently causes compatibility issues in cross-platform development. When scripts with \r\n line endings are executed in Unix environments, the shebang line (e.g., #!/usr/bin/env bash) is parsed as #!/usr/bin/env bash\r, preventing the system from locating an interpreter named bash\r.
Quick Fix Solution
For urgent situations, the sed command can be used to remove carriage returns from the script:
sed $'s/\r$//' ./install.sh > ./install.Unix.sh
This utilizes ANSI-C quoted strings $'...', a feature supported in bash, ksh, and zsh, ensuring that \r is properly expanded to an actual carriage return character before sed processes it. Since some sed implementations do not natively support the \r escape sequence, this preprocessing approach is more reliable. The processed script can then be executed normally via ./install.Unix.sh --clang-completer.
Git Configuration and Line Ending Conversion
The root cause often lies in Git's automatic line ending conversion feature. In Windows environments, Git's default configuration core.autocrlf=true converts Unix-style \n to Windows-style \r\n during file checkout, and performs the reverse conversion during commit. While this is beneficial for Windows development environments, it causes issues in scenarios involving script execution.
To temporarily disable this feature, execute:
git config --global core.autocrlf false
This ensures Git checks out files in their original format, preserving Unix-style line endings. After completing the installation, the default setting can be restored with git config --global core.autocrlf true.
Related Cases and Verification
In pyenv's Issue #1725, users reported a similar problem: when executing pyenv --help in a Debian environment under WSL2, the error /usr/bin/env: ‘bash\r’: No such file or directory occurred. The solution was similarly to remove carriage returns:
cd ~/.pyenv && find . -type f | xargs sed -i $'s/\r$//' && cd -
This demonstrates that such issues are quite common in cross-platform environments like WSL, requiring special attention from developers.
Preventive Measures and Best Practices
To avoid similar issues, it is recommended to: uniformly use Unix-style line endings in cross-platform projects; explicitly specify text file handling in .gitattributes files; incorporate line ending checks in CI/CD pipelines; and for critical script files, fix their line ending format in version control.
In-depth Technical Details
The mechanism of ANSI-C quoted strings warrants deeper understanding: in bash, the $'...' syntax allows the use of C-style escape sequences such as \n, \r, \t, etc. This makes handling special characters in scripts more intuitive and reliable. Meanwhile, sed's -i option supports in-place file modification, but backing up original files is advised in production environments.