Can't run most basic commands due to CRLF: ls\r not found
Endle opened this issue · 8 comments
Proof of concept:
on:
push:
branches: [ develop,cygwin ]
pull_request:
branches: [ develop ]
workflow_dispatch:
jobs:
win-build-upstream-mono:
runs-on: windows-2019
steps:
- uses: actions/checkout@v2
- name: Set up Cygwin
uses: egor-tensin/setup-cygwin@v3
with:
platform: x64
packages: git unzip
- name: check env
shell: bash
run: |
ls
pwd
ls -a
I have such error:
Run ls
ls
pwd
ls -a
shell: C:\tools\cygwin\bin\bash.EXE --noprofile -e -o pipefail {0}
env:
CYGWIN:
D:\a\_temp\a2ea1fad-fdcb-46f8-8a2c-62d654473fda: line 1: $'ls\r': command not found
Error: Process completed with exit code 127.
@Endle Hello! You're doing it a bit wrong, I'm afraid. First, bash really doesn't like \r\n line endings. To work around that in Cygwin, you need to pass the -o igncr
option. Second, I'm pretty sure that Cygwin's bash requires that you invoke it as a "login shell" (using --login
). To make it work, you can do something like this:
steps:
- name: check env
run: |
ls
pwd
ls -a
shell: C:\tools\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}'
For an example, please see my test workflow at
setup-cygwin/.github/workflows/test.yml
Line 79 in d9b45e8
But you don't even need to do that, since Cygwin's /usr/bin (as well as /usr/local/bin) is added to the system PATH, so you can just call ls and pwd directly:
steps:
- name: check env
run: |
ls.exe
pwd.exe
ls.exe -a
Thank you! Using the full configuration resolves my problem
shell: C:\tools\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}'
I created a PR for those who may have similar doubts #5
Recent bash for cygwin 4.4.12(3)-release
is broken: it didn't want to propagate igncr
:
C:\cygwin64\bin\bash.exe -o igncr
echo $SHELLOPTS
> braceexpand:emacs:hashall:histexpand:history:igncr:interactive-comments:monitor
bash
echo $SHELLOPTS
> braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
That's why any subscript fails, so bash -o igncr
is not a solution. Setting SHELLOPTS
directly is not possible: cygwin
developers made it readonly. MSVC
and regular cmd
support today is much simplier than cygwin
.
If SHELLOPTS
should not be inherited by design so igncr
should not be a part of SHELLOPTS
. igncr
is a special workaround for windows that should live his own life outside of SHELLOPTS
logic. It is not possible to explain this simple idea for cygwin
developers, so we have to somehow put this crowbar directly.
C:\cygwin64\bin\bash.exe -cl "env SHELLOPTS=igncr bash"
echo $SHELLOPTS
> braceexpand:emacs:hashall:histexpand:history:igncr:interactive-comments:monitor
bash
echo $SHELLOPTS
> braceexpand:emacs:hashall:histexpand:history:igncr:interactive-comments:monitor
--norc
is not really required, rc
files is mostly noop, it is better to manage pipefail
in script itself, so solution looks as follows:
run: C:\cygwin64\bin\bash.exe -cl "env SHELLOPTS=igncr '%cd%\scripts\some.sh'"
Thank you.
@andrew-aladev I don't think anything's broken; I just run the test workflow and it works fine with shell:
: https://github.com/egor-tensin/setup-cygwin/actions/runs/790816641.
cygwin developers made it readonly
AFAIR, SHELLOPTS has always been read-only; it's readonly on all my Linux machines. Quote from the manual (as read on Linux):
This variable is read-only.
I think it's meant to be modified using set -o
.
Now, in your example, igncr works fine for the outer instance of bash. The inner instance of bash doesn't inherit SHELLOPTS, and it never does this not on Cygwin, nor on Linux. To make it inherit SHELLOPTS, you need to either put export SHELLOPTS
in your .bashrc, or put SHELLOPTS in your environment. For example, from a cmd
prompt:
> set SHELLOPTS=igncr
> bash.exe --login -c "bash -c 'echo $SHELLOPTS'"
braceexpand:hashall:igncr:interactive-comments
Same from a Cygwin prompt:
# env SHELLOPTS=igncr bash -c 'bash -c "echo $SHELLOPTS"'
braceexpand:hashall:igncr:interactive-comments
Take a look at this question for reference: https://unix.stackexchange.com/q/387186
@andrew-aladev Please either don't use nested bash invocations (is there way around it? This issue was about a legitimate use-case concerning GitHub Actions.), or put something like SHELLOPTS: igncr
in the env:
block of your workflow jobs.
Hello @egor-tensin, your test script doesn't include subscripts, so it won't fail. You can include any subscript and it will fail.
SHELLOPTS has always been read-only; it's readonly on all my Linux machines
This is just design limitation made by bash
developers, you shouldn't consider it serious.
Please either don't use nested bash invocations
Real world application uses high degree of inheritance, why not? This is just bash
. But bash
!== cygwin bash
, bash
developers will never add igncr
into SHELLOPTS
.
Please consider adding some sort of SHELLOPTS=igncr
universal workaround in README
.
You can include any subscript and it will fail.
Yes, if the "sub" script has \r\n as line terminators. In which case any Linux bash will choke on it too (I think it's stupid BTW). bash scripts run on Cygwin also tend to be run on real Linux machines quite often, so scripts writers should make sure \n is used as line terminator in their scripts (I do this using .gitattributes).
Please consider adding some sort of SHELLOPTS=igncr universal workaround in README.
I will, thanks.
Done