3

Commands in PowerShell are almost like Bash, but the dot notation expansion is creating a lot of work for me. Currently I have to wrap a lot of command parameters in quotes:

.\mvnw.cmd -Dmaven.repo.local=.m2/repository deploy:deploy-file -Durl=http://zippo:8081/repository/grinch/ -DrepositoryId=nexus -DgroupId=com.zippo -DartifactId=test -Dversion=1.0 -Dpackaging=jar -Dfile=test-1.0.jar

becomes

.\mvnw.cmd -D"maven.repo.local"=".m2/repository" deploy:deploy-file -Durl=http://zippo:8081/repository/grinch/ -DrepositoryId=nexus -DgroupId="com.zippo" -DartifactId=test -Dversion="1.0" -Dpackaging=jar -Dfile="test-1.0.jar"

How can I disable dot notation, or override the dot operator, replace it with something else, etc.?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
caduceus
  • 1,542
  • 2
  • 16
  • 21
  • Give the full path of the `mvnw.cmd` instead of the Dot. And I would recommend using [GRADLE WRAPPER](https://docs.gradle.org/current/userguide/gradle_wrapper.html) instead of maven wrapper. – Ranadip Dutta Mar 25 '21 at 08:06
  • 5
    PowerShell offers the stop-parsing symbol (`--%`) for this : `.\mwnw.cmd --%` and then the rest of your command line. – Jeroen Mostert Mar 25 '21 at 09:06
  • Maybe I misunderstood this question. I thought this question was to disable autocomplete adding a .\. – Garret Wilson Sep 07 '22 at 13:28
  • I've added a new question at https://superuser.com/q/1741125 which exactly matches what I opened the bounty for here. – Garret Wilson Sep 07 '22 at 13:37
  • 2
    FYI https://github.com/PowerShell/PowerShell/issues/15541 – caduceus Sep 07 '22 at 13:45
  • I originally posted a bounty for this question because, being new to PowerShell, I had confused it with [another issue](https://superuser.com/q/1741125). But now this issue is starting to bite me. (I have to change the way I invoke Java just to use PowerShell??! Incredible.) So I'm glad I put a bounty on this question after all. Too bad there is no real workaround. – Garret Wilson Mar 16 '23 at 16:31

1 Answers1

8

How can I disable dot notation?

  • The problem isn't dot notation, it is a bug in how PowerShell parses arguments to be passed to external programs:

  • Escaping or quoting is indeed needed to work around this problem, but you can simplify it by `-escaping the initial - of each affected argument or by enclosing each as a whole in '...' (or "...", if you need string interpolation):

    # `-escape the initial - of all affected arguments.
    .\mvnw.cmd `-Dmaven.repo.local=.m2/repository deploy:deploy-file -Durl=http://zippo:8081/repository/grinch/ -DrepositoryId=nexus `-DgroupId=com.zippo -DartifactId=test `-Dversion=1.0 -Dpackaging=jar `-Dfile=test-1.0.jar
    
    # Alternative: Quote the affected arguments.
    .\mvnw.cmd '-Dmaven.repo.local=.m2/repository' deploy:deploy-file -Durl=http://zippo:8081/repository/grinch/ -DrepositoryId=nexus '-DgroupId=com.zippo' -DartifactId=test '-Dversion=1.0' -Dpackaging=jar '-Dfile=test-1.0.jar'
    
    • If you don't want to have to think about which specific arguments may be affected, quote them all, which - combined with the fact that you can pass arguments as an array of strings, using @(...), the array-subexpression operator - can be used to make a long command more readable, by spreading it across multiple lines:

      .\mvnw.cmd @(
        '-Dmaven.repo.local=.m2/repository'
        'deploy:deploy-file' 
        '-Durl=http://zippo:8081/repository/grinch/'
        '-DrepositoryId=nexus' 
        '-DgroupId=com.zippo'
        '-DartifactId=test'
        '-Dversion=1.0'
        '-Dpackaging=jar'
        '-Dfile=test-1.0.jar'
      )
      

Alternatives:

  • You can use --%, the stop-parsing token, which obviates the need for quoting, but note its many limitations, notably the inability to (directly) incorporate PowerShell variables and expressions into the command - see this answer for details.

    # --% passes the remainder of the command line as-is to the target program
    .\mvnw.cmd --% -Dmaven.repo.local=.m2/repository deploy:deploy-file -Durl=http://zippo:8081/repository/grinch/ -DrepositoryId=nexus -DgroupId=com.zippo -DartifactId=test -Dversion=1.0 -Dpackaging=jar -Dfile=test-1.0.jar
    
  • You can call via cmd /c, in which case you can quote your entire command line, which avoids the parsing bug (though note that the command specified in the string must then satisfy cmd.exe's syntax rules; they can differ from PowerShell's, albeit not in this case):

    cmd /c '.\mvnw.cmd -Dmaven.repo.local=.m2/repository deploy:deploy-file -Durl=http://zippo:8081/repository/grinch/ -DrepositoryId=nexus -DgroupId=com.zippo -DartifactId=test -Dversion=1.0 -Dpackaging=jar -Dfile=test-1.0.jar'
    
mklement0
  • 382,024
  • 64
  • 607
  • 775
  • 1
    So after using PowerShell quite a while and getting to know it better, whatever benefits it brings (parameter parsing is great—except [when it's not](https://github.com/PowerShell/PowerShell/issues/18387)), it seems to negate with basic blunders such as this one. I had started to [build bigger things with PowerShell](https://www.garretwilson.com/blog/2023/01/04/fix-manning-epub), but if I have to change the way I've invoked Java since 1997 or so, then I've realized that I might as well use Git Bash or WSL, deal with a few Bash quirks, and be happy with something that runs basically everywhere. – Garret Wilson Mar 16 '23 at 16:36
  • @GarretWilson, I share your frustration that such basic bugs have been allowed to linger for years. However, note that even if they were fixed, there will still be - unavoidable - cases where command lines behave differently than in other shells, given the different escape character (`\`` vs. `\`) and PowerShell's additional metacharacters (e.g., `@`). Unlike the annoying bugs, these difference are the unavoidable price you pay for, in part, PowerShell's Windows heritage (escape char.), but, on the plus side, for its superior argument-passing capabilities and type support. – mklement0 Mar 16 '23 at 16:53
  • 1
    I hear what you're saying @mklement0, and if these were corner cases or rare cases or cases that traded far superior functionality for a little twist in syntax, I would completely understand. But breaking the most common day-to-day use cases in exchange for buggy "superior" functionality gets frustrating after a while. Thanks for the empathy. – Garret Wilson Mar 16 '23 at 16:58
  • I thought I would be clever and at least add some one-off `$PROFILE` functions to work around this for certain commands such as [invoking Java with system properties](https://stackoverflow.com/a/1520376), e.g. `java -jar -Dfoo.bar=test example.jar`. I tried `function java {java.exe --% @args}` but that didn't work. Neither did `function java {java.exe --% $args}`. Any ideas? – Garret Wilson Mar 16 '23 at 20:07
  • @GarretWilson, unfortunately, you cannot solve this via a function to which you pass individual arguments, because the problem is how those individual arguments are parsed (except if you quote them). If you want a helper function, make it accept a _single string_ with a command line for `cmd /c` / `sh -c`, and invoke it via the latter. – mklement0 Mar 16 '23 at 20:24
  • I appreciate that you've continued to think about this. But I'm pretty much a lost cause now. All these PowerShell bugs and issues piled up (not even mentioning that it takes several seconds just to get a PowerShell prompt). I finally threw in the towel switched to Git Bash several months ago, and I'm liking my decision better every day. Plus my scripts are truly cross platform now. PowerShell was a great idea that, like many great ideas Microsoft took and ran with, is now just a hobbled, buggy, inconsistent weight to tie me down and add more irritations to my day. – Garret Wilson Jul 17 '23 at 19:48
  • @GarretWilson, I hear you with respect to the frustration over long-standing bugs not getting fixed, as well as historical warts that cannot get fixed, because doing so would break backward compatibility. That said, PowerShell's scripting language is vastly superior to that of Bash and virtually all other shells, and another pain point - the lack of raw byte handling in the pipeline, is finally getting addressed: https://learn.microsoft.com/en-us/powershell/scripting/learn/experimental-features#psnativecommandpreservebytepipe (only an _experimental_ feature at this point). – mklement0 Jul 17 '23 at 20:13
  • 1
    "… PowerShell's scripting language is vastly superior to that of Bash and virtually all other shell …." That's probably true, but it's missing the point. Most of the things I want to do in the shell are relatively simple things, which PowerShell gunks up. If I have a task that needs a "vastly superior" language, I wouldn't even be using a shell scripting language at that point—that's what Python, Node, and Java are for. Heck, even Rust. But for the simple things I want a shell script for, PowerShell lets me down. But I stress again I appreciate the input and help you've given me, @mklement0. – Garret Wilson Jul 17 '23 at 22:43