If an interpreter path ends with ^M, inspect the first line for carriage-return bytes. Adding execute permission cannot repair a CRLF shebang. Convert a reviewed text copy to LF and check the complete diff before replacing the original.
Reproduce in an empty temporary directory
This isolated example creates only fixture data in its working directory or runs local JavaScript. Run it separately from your project so the named files cannot overwrite real work.
# Disposable fixture only; do not run this over an existing script.
printf '#!/bin/bash\r\nprintf "hello\\n"\r\n' > crlf.sh
od -An -tx1 -N 16 crlf.sh
python3 - <<'PY'
from pathlib import Path
raw = Path('crlf.sh').read_bytes()
assert b'\r\n' in raw
Path('lf.sh').write_bytes(raw.replace(b'\r\n', b'\n'))
assert b'\r' not in Path('lf.sh').read_bytes()
PY
bash -n lf.sh
bash lf.shObserved local output
23 21 2f 62 69 6e 2f 62 61 73 68 0d 0a 70 72 69
helloWhat to compare
The hex dump shows 0d 0a at the first line ending. The reviewed copy uses 0a. The syntax check and explicit Bash invocation then validate that copy in this fixture. Executing a file directly also involves operating-system interpreter handling; the exact error wording varies. Inspecting bytes avoids relying on how a terminal renders the control character.
Choose the next action
Confirm that the file is a text script and preserve its original before conversion. Use the editor line-ending control or a narrowly scoped byte conversion, then review the diff and run the relevant syntax check. In a repository, establish a deliberate .gitattributes policy for scripts so future checkouts preserve the expected endings. Inspect an unexpected encoding marker separately rather than assuming every interpreter error is CRLF.
Limits and verification
The conversion shown only replaces CRLF pairs in a generated fixture. It does not delete every carriage return from an arbitrary file, modify repository settings or change executable permission. A missing interpreter, wrong architecture and no-execute filesystem can cause different launch failures and require different evidence. The source describes interpreter selection; the byte-level fixture supplies the local line-ending observation.
Related: Printf Misreads Percent Signs in a Variable: Keep the Format Literal.
Isolated example executed on macOS on November 10, 2026 (KST), using Bash 3.2, Python 3 for the byte fixture, and Node v26.5.0. Results describe the example, not your application or every runtime version.