Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't run most basic commands due to CRLF: ls\r not found #4

Closed
Endle opened this issue Mar 2, 2021 · 8 comments
Closed

Can't run most basic commands due to CRLF: ls\r not found #4

Endle opened this issue Mar 2, 2021 · 8 comments

Comments

@Endle
Copy link

Endle commented Mar 2, 2021

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.
@egor-tensin
Copy link
Owner

@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

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

@Endle
Copy link
Author

Endle commented Mar 4, 2021

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

@andrew-aladev
Copy link

andrew-aladev commented Apr 27, 2021

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.

cygwin developer

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.

@egor-tensin
Copy link
Owner

@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

@egor-tensin
Copy link
Owner

@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.

@andrew-aladev
Copy link

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.

@egor-tensin
Copy link
Owner

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.

@egor-tensin
Copy link
Owner

Done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants