Starting with the execution context so that the problem makes sense:

I am running scripts written in Windows Subsystem for Linux. In this context, scripts written can sometimes accumulate carriage return characters in addition to newline characters (\r\n).

This is often unpredictable -- it is probably my mistake, but I am not interested in learning how not to make that mistake -- so I would like to have a robust way to execute scripts with carriage return characters.

What I have come up with so far is bumping up against a security layer:

<(sed 's/\r//g' script.sh)

bash: /dev/fd/63: Permission denied

In this case, I have not made the file socket (or whatever it is under the hood) executable.

bash <(sed 's/\r//g' script.sh) # works
bash <(sed 's/\r//g' foo.py) # ignores foo's hash-bang and fails

The second option fails because the hash-bang at the top of the python file has been ignored or I missed some call step.

A (temporary) option is:

python3 <(sed 's/\r//g' script.py)

However, this is problematic due to the versioning of the python binary (python<version#>), which is best handled at the #! ... line internal to the script.

Also, it will fail for the ecosystem of other hash-bangables -- I'll have to be specific everywhere, which is sort of a big bump in the snarliness of my little bite-sized scripts.

Is there a way to make this executable, not ignore the hash-bang, or a way to solve the overall problem differently?


Fix the broken file pre-emptively before executing it:

dos2unix script.py

For interactive use, use a wrapper script to fix the file before executing it. Create a file name run_broken_file.sh with the following content:

dos2unix "$1"

And then you can run ./run_broken_file.sh ./script.py arg1 arg2 arg3

Sample run:

$ unix2dos script.py 
unix2dos: converting file script.py to DOS format...

$ ./script.py 
/usr/bin/env: ‘python3\r’: No such file or directory

$ cat -A script.py 
#!/usr/bin/env python3^M$
import sys^M$
print(f"hello {sys.argv}")^M$

$ cat run_broken_file.sh 
dos2unix "$1"

$ ./run_broken_file.sh ./script.py arg1 arg2 'arg3 with spaces'
dos2unix: converting file ./script.py to Unix format...
hello ['./script.py', 'arg1', 'arg2', 'arg3 with spaces']

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.