1

MSYS2-built Linux applications internally rewrite Linux paths to Windows paths.

This can be problematic if those are supposed to interface with other, proper-Linux applications (e.g. in my case, MSYS2 rsync connecting to a Debian 12 rsync server).

It can be configured but neither are the means particularly elegant nor are they particularly dependable, it would seem.

There is however a very appealing shorthand: Use an absolute path prefixed with a second /.

e.g. /home/me/something will become C:\msys64\home\me\something but //home/me/something will remain unchanged (and the rsync server treats it as single / at least on Debian 10 and 12).

I am using MSYS2 to make a single Windows machine work mostly-seamlessly in an environment otherwise dominated by Debian 12 machines, wanting to use the same tools/scripts there, if possible, so I wonder:

Can I presume a path beginning with // equals a path starting with / on all or most Linux distributions / for all or most common CLI tools?

As per the Unix standard, interpretation of the first slash in // is implementation-defined. But what do the implementations define?

(This question deals with the native Linux side, but if you just happen to know whether this is a stable solution on the MSYS2 side, I would be grateful for mentioning it.)

5
  • 1
    See stackoverflow.com/a/20690872/10622916 Commented Jan 21 at 17:03
  • @Bodo : Good hint. Unfortunately 'Implementation-defined manner' does not quite suffice without knowing how the implementations define it. E.g. "Debian-based distributions guarantee this but Arch-based ones does not." might be an acceptable answer. I do not care about an exhaustive list, but a somewhat quantificative and taxonomic rule-of-thumb would be great. Commented Jan 21 at 17:17
  • 1
    Citing a comment to stackoverflow.com/a/16841471/10622916: "On my git bash emulation (technically a windows machine) an attempt to ls -l // results in the machine trying to read and list the entire available network..." So you might observe unexpected interpretation of paths starting with a double slash in some environments. As far as I know, Git Bash is based on MSys2. Commented Jan 22 at 10:08
  • @Bodo : Yes it is. Interesting. I tried to reproduce in both git-bash from 'git for Windows' 2.42.0.windows.2 and bash of MSYS-UCRT64 3.5.4-0bc1222b.x86_64 - in both ls -l // emits ls: reading directory '//': No such file or directory as expected. (/ would be silently replaced by C:/msys64/ and verbatim it really does not exist.) Maybe this behaviour recently changed. I hope to eventually receive a response to the respective question in my msys-packages issue... Commented Jan 22 at 12:11
  • windows via MSYS2: rhash --path-separator='/' = "RHash: path-separator is neither '/' nor '\': C:/msys64/" ----- linux CLI: rhash --path-separator='//' = "RHash: path-separator is neither '/' nor '\': //" . consensus: // is not always portable. Commented Nov 16 at 7:54

1 Answer 1

0

Closest option i can think of for being portable:

if grep -q -s '^ID=msys2\?$' /etc/os-release; then printf //; else printf /; fi 

(or a little more compact if you prefer):

if grep -qs '^ID=msys2\?$' /etc/os-release;then printf //;else printf /;fi 

I don't have MSYS1 available to test if it has /etc/os-release, but in the event it does, this should in-theory work. Tested and confirmed working on MSYS2, OS X El Capitan (no /etc/os-release), OpenBSD 7.3 (no /etc/os-release), Debian 13 and Arch.


Example where '/' and '//' are judged differently:

MSYS2 (manual specification):

$ rhash --path-separator='/' --simple dir/file.txt RHash: path-separator is neither '/' nor '\': C:/msys64/ $ rhash --path-separator='//' --simple dir/file.txt 588aa4ac dir/file.txt 

*nix OSes (GNU+Linux, *BSD, etc) (manual specification):

$ rhash --path-separator='/' --simple dir/file.txt 588aa4ac dir/file.txt $ rhash --path-separator='//' --simple dir/file.txt RHash: path-separator is neither '/' nor '\': // 

This check looks to print '/' or '//' accordingly:

MSYS2 (automated specification):

$ rhash --path-separator="$(if grep -q -s '^ID=msys2\?$' /etc/os-release; then printf //; else printf /; fi)" --simple dir/file.txt 588aa4ac dir/file.txt 

*nix OSes (GNU+Linux, *BSD, etc) (automated specification):

$ rhash --path-separator="$(if grep -q -s '^ID=msys2\?$' /etc/os-release; then printf //; else printf /; fi)" --simple dir/file.txt 588aa4ac dir/file.txt 
2
  • There is the possibility that a '//'-requiring OS also lacks an /etc/os-release file, but the chances seem...quite low? I hope? Commented Nov 16 at 8:45
  • Even smaller/easier if your shell can support (worked on above OSes): ckslash(){ if grep -q -s '^ID=msys2\?$' /etc/os-release; then printf //; else printf /; fi; } then in practice: rhash --path-separator=$(ckslash) --simple dir/file.txt Commented Nov 18 at 4:22

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.