Search code examples
windowsbashpowershellpath-separator

Keep backslashes when passing path param in bash from powershell


I have a powershell .ps1 script where I am calling a ./configure script like this:

bash ./configure --prefix="$my_path"

my_path variable is some dynamic path like C:\jenkins\mydir\84534yfiybsdl\Temp that becomes C:jenkinsmydir84534yfiybsdlTemp in ./configure script and I believe I'd need to pass "C:\/jenkins\/mydir\/84534yfiybsdl\/Temp" for it to work.

I tried to use -replace '\', '/' earlier in powershell before calling the script, and --prefix="${my_path////\/}" and even --prefix="$(my_path)" but nothing worked. Would appreciate any help!


Solution

  • Passing your path with / rather than \ as the path separator may work:

    bash ./configure --prefix="$($my_path.Replace('\', '/'))"
    

    If \ must be used, escape them as \\:

    bash ./configure --prefix="$($my_path.Replace('\', '\\'))"
    

    Assuming you're using WSL, you could avoid the problem altogether if you call via wsl -e as follows:

    wsl -e bash ./configure --prefix=$my_path
    

    Note: -e is short for --exec; the wsl.exe overview page is currently limited to documenting CLI options related to distro management; use wsl --help to see all options.


    The original problem is caused by the - now deprecated - bash.exe WSL CLI inappropriately parsing its arguments as if they had been provided from inside a Bash session, causing undesired interpretation of what should be verbatim arguments:

    • Notably, verbatim \ characters unexpectedly become escape characters, which breaks arguments that contain (unescape) Windows path strings, and $-prefixed arguments are expanded up front.

    • When calling via wsl -e, no such undesired interpretation occurs.

    Example:

    The following uses an ad-hoc bash script to echo the first argument it is given (the last argument on the command line, a\b):

    • Calling via wsl -e passes the arguments through verbatim:

      # OK: -> 'a\b'
      wsl.exe -e bash -c 'printf %s $1' - a\b 
      
    • To counteract the undesired up-front interpretation performed by bash.exe, you must unexpectedly escape both the $ and \ characters:

      # !! Unexpected need to \-escape $ and \ to get output 'a\b'
      bash.exe -c 'printf %s \$1' - a\\b