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

Issue: Slash-prefixed arguments needs to be doubly escaped in msys64/Git Bash #198

Open
musjj opened this issue Nov 3, 2022 · 4 comments

Comments

@musjj
Copy link

musjj commented Nov 3, 2022

Issue Description

Built-in Windows tools like tasklist, taskkill, etc. uses slash-prefixed arguments like /A, /B, etc.
This is in conflict with Git Bash's parsing magic which converts them to Windows paths, so we need to escape it:

$ taskkill /?
ERROR: Invalid argument/option - 'C:/msys64/?'.
Type "TASKKILL /?" for usage.

$ taskkill //?

TASKKILL [/S system [/U username [/P [password]]]]
         { [/FI filter] [/PID processid | /IM imagename] } [/T] [/F]

Description:
    This tool is used to terminate tasks by process id (PID) or image name.
...

But when using sudo, for some reason you need to escape it twice:

$ sudo tasklist /?
ERROR: Invalid argument/option - 'C:/msys64/?'.
Type "TASKLIST /?" for usage.

$ sudo tasklist //?
ERROR: Invalid argument/option - 'C:/msys64/?'.
Type "TASKLIST /?" for usage.

$ sudo tasklist ///?

TASKLIST [/S system [/U username [/P [password]]]]
         [/M [module] | /SVC | /V] [/FI filter] [/FO format] [/NH]

Description:
    This tool displays a list of currently running processes on
    either a local or remote machine.
...

What is causing this to happen?

Steps to Reproduce

  1. Open a msys64/Git Bash shell
  2. Run tasklist /? and tasklist //? and compare their output
  3. Run sudo tasklist /?, sudo tasklist //?, and sudo tasklist ///? and compare their output

Context:

  • Windows version: Microsoft Windows [Version 10.0.19043.2130]
  • gsudo version: gsudo v1.3.0 (Branch.master.Sha.24fb735f547e1e5dd7aa22fdd77777fa8c923a1c)
@gerardog
Copy link
Owner

gerardog commented Nov 3, 2022

It behaves differently on my machine. Please upgrade to latest gsudo and latest git.
If you have winget, do winget upgrade git.git and winget upgrade gerardog.gsudo

@gerardog
Copy link
Owner

gerardog commented Nov 3, 2022

I can see it If I use /IM

image

On each process hop it eats one '/'.

@gerardog
Copy link
Owner

gerardog commented Nov 3, 2022

The way I thought of using it from bash is to use it as gsudo, to not confuse it with the original sudo... There is actually a gsudo (no extension) bash wrapper in the gsudo installation folder, which sets
MSYS_NO_PATHCONV=1.... hence disabling the path conversion...

You may want go to your gsudo folder and duplicate gsudo into sudo to feel how that feature would feel.

I'm busy right now to give you a perfect answer... The problem with Msys2 path mangling is that I couldn't find a way to ensure the path is mangled just once.

We have 2/3 tools at hand.

  • The gsudo bash wrapper that definitely also exist as sudo
  • A possible sudo/gsudo profile function such as sudo() { WSLENV=WSL_DISTRO_NAME:USER:$WSLENV MSYS_NO_PATHCONV=1 gsudo.exe "$@"; }
  • gsudo.exe itself doing command line replacements.

There should be a combination of those 3 that should make gsudo prefix transparent to path mangling, but I couldn't find one. It's either making the conversion twice or none.

@musjj
Copy link
Author

musjj commented Nov 4, 2022

Thanks for the hint with the environment variable.
I'm using MSYS2, so MSYS_NO_PATHCONV=1 doesn't work for me (the variable only applies to the Git For Windows fork of MSYS), so I need to use MSYS2_ARG_CONV_EXCL="*" instead.
It seems that setting the variable works immediately for the running command, so escaping slashes is not needed at all:
MSYS2_ARG_CONV_EXCL="*" sudo tasklist /?
Now all I need to do is to turn it into a function in my .bashrc for convenience.

EDIT: Actually, thinking about it, this behaviour is undesirable. I would want the slashes to be parsed once, in case I actually want to pass MSYS paths to the program.
So I changed it to:
sudo() { sudo.exe MSYS2_ARG_CONV_EXCL="'*'" "$@"; }
And it seem to work the way I wanted it to, but for some reason it made the startup time really slow compared to:
sudo() { MSYS2_ARG_CONV_EXCL="*" sudo.exe "$@"; }
Do you have any idea what's causing the slowdown?

EDIT 2: It seems that there is an issue with Bash trying to expand the ?.
For some reason the issue doesn't happen with a single slash (e.g. echo /?), but with a double slash the command slows down or even downright freezes: (e.g. echo //?)
Escaping it like this: //\? seems to fix the issue.

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

2 participants