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

Newlines and Carriage Returns Following $() Command Substitution Cause Bash Parse Error #3303

Closed
1 task done
zedseven opened this issue Jul 1, 2021 · 8 comments
Closed
1 task done
Labels

Comments

@zedseven
Copy link

zedseven commented Jul 1, 2021

  • I was not able to find an open or closed issue matching what I'm seeing (apologies if I missed one)

Setup

I'm Using Git-2.32.0-64-bit, the latest release as of writing:

$ git --version --build-options

git version 2.32.0.windows.1
cpu: x86_64
built from commit: 4c204998d0e156d13d81abe1d1963051b1418fc0
sizeof-long: 4
sizeof-size_t: 8
shell-path: /bin/sh
feature: fsmonitor--daemon

I'm running Windows 10 64-bit:

$ cmd.exe /c ver

Microsoft Windows [Version 10.0.19041.1052]

My installation options:

$ cat /etc/install-options.txt

Editor Option: VIM
Custom Editor Path:
Default Branch Option: main
Path Option: CmdTools
SSH Option: OpenSSH
Tortoise Option: false
CURL Option: OpenSSL
CRLF Option: CRLFAlways
Bash Terminal Option: MinTTY
Git Pull Behavior Option: Merge
Use Credential Manager: Core
Performance Tweaks FSCache: Enabled
Enable Symlinks: Disabled
Enable Pseudo Console Support: Enabled
Enable FSMonitor: Disabled

Any other interesting things about your environment that might be related to the issue you're seeing?

I decided to make a custom .bashrc for my Windows installation, including setting up a custom $PS1. This is where I encountered the issue.

Details

Which terminal/shell are you running Git from? e.g Bash/CMD/PowerShell/other

I'm running MSYS2, Git Bash.

What commands did you run to trigger this issue?

Run the following:

export PS1='$(echo test)\n'
# or
export PS1='$(echo test)\r'

After running either of these, every time $PS1 is evaluated, bash outputs an error:

bash: command substitution: line 1: syntax error near unexpected token `)'
bash: command substitution: line 1: `echo test)'
APitaD9vi0.mp4
T9UOAS7l1R.mp4

The cause is the newline or carriage return character. If it's removed, the $PS1 works as expected:

xqiRFZP3Rm.mp4

This seems to be a long-known issue exclusive to Git for Windows (https://stackoverflow.com/a/41925324/6003488) however there's more that I found.

Replacing the $() with backticks avoids the issue for both the newline and carriage return:

export PS1='`echo test`\n'
export PS1='`echo test`\r'
w7tjdwuHHR.mp4
bTLHlczZp0.mp4

And replacing the newline character with it's ASCII character code also avoids the issue, but this only works for the newline:

# https://stackoverflow.com/a/41925324/6003488
# works:
export PS1='$(echo test)\012'
# doesn't work:
export PS1='$(echo test)\015'
ByzCwZjmRU.mp4
h4EQlxdHcQ.mp4

Outputting the newline as a direct character sequence works, but doing the same with a carriage return doesn't work:

# https://stackoverflow.com/a/21561763/6003488
# works:
export PS1='$(echo test)'$'\n'
# doesn't work:
export PS1='$(echo test)'$'\r'
wq85YFEenu.mp4
IIUOqH5pew.mp4

Outputting the characters from a separate function seems to work so long as the function call is done every time $PS1 is evaluated, rather than upon definition:

# https://stackoverflow.com/a/37074809/6003488
function echocr() {
    echo -e -n "\r"
}
# works (because echocr is called every evaluation):
export PS1="\$(echo test)\$(echocr)"
# doesn't work (because echocr is evaluated once and put in $PS1 directly):
export PS1="\$(echo test)$(echocr)"
gEb2sMTd4L.mp4
7rsPVSRQ3j.mp4

What did you expect to occur after running these commands?

I expected the new $PS1 variable to be evaluated without error, the same way the bash string would be if used outside of $PS1.

What actually happened instead?

I got an obscure, unhelpful error that indicated the bash installation was having trouble parsing the new $PS1 variable, even though it should be valid bash.

Additional Notes

Apologies if there exists an issue that mentions this already. I looked and didn't find one, and figured I'd gather all the information I know about the issue and post it so it can hopefully finally be resolved.

I don't know much more about the issue, other than this. I was able to work around the problem by using the separate function method for my use of a carriage return, but obviously that's not a proper solution.

@dscho
Copy link
Member

dscho commented Jul 2, 2021

Does this also happen in a regular MSYS2 Bash?

@dscho
Copy link
Member

dscho commented Jul 2, 2021

BTW you can easily work around that issue:

PS1='$(echo test)
'

(Note the literal line break before the closing quote, and also note that you need not export this variable.)

@dscho dscho added the question label Jul 2, 2021
@zedseven
Copy link
Author

zedseven commented Jul 2, 2021

Just tested it, and it looks like it does (though I haven't tested every single case, the simple case of PS1='$(echo test)\n' fails).

Does this mean the issue needs to be raised somewhere else?

@zedseven
Copy link
Author

zedseven commented Jul 2, 2021

The problem that led me to actually create this issue was that of the carriage return - enough workarounds exist for the newline character, but very few also work with the carriage return which led to a bit of a headache.

As I said before I was able to work around this, but it was a bit annoying to say the least.

@dscho
Copy link
Member

dscho commented Jul 12, 2021

Just tested it, and it looks like it does (though I haven't tested every single case, the simple case of PS1='$(echo test)\n' fails).

Does this mean the issue needs to be raised somewhere else?

The next step to test would be Cygwin. MSYS2 is a close derivative of Cygwin, and to pinpoint where exactly the bug exists, it would be good to know whether Cygwin shares the behavior of MSYS2's.

@zedseven
Copy link
Author

Looks like Cygwin doesn't have an issue with any of the tests, and behaves as expected.

ndDIiugC6p.mp4

I also went back and tested MSYS2 again, and found that newer installations of it still failed, but with different error messages.

An older installation (Bash 4.4.023-1):

S9p5YwSFiZ.mp4

A newer installation (Bash 5.1.004-1):

OIzpiejwYU.mp4

(I just wrote the Bash versions above as markers of their approximate age, since afaik MSYS2 doesn't have a canonical version. That's also why I included the output of pacman -Q)

@dscho
Copy link
Member

dscho commented Aug 29, 2023

Closing as stale.

@dscho dscho closed this as not planned Won't fix, can't repro, duplicate, stale Aug 29, 2023
@akinomyoga
Copy link

The problem still exists. It's reported in the upstream MSYS2: msys2/MSYS2-packages#1839

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

No branches or pull requests

3 participants