DavidT
DavidT

Reputation: 767

`doskey /macros:all` produces quoted string I can't get rid of

First, I'm in PowerShell and I've entered the doskey /exename=powershell.exe option.

Second, I did something that I now realize doesn't quite work:

doskey envpath=$env:Path -split ';' 

The goal was to have it print the path environment variable (whatever it is at the time I later enter envpath). However, it seems to have evaluated $env:Path while defining the macro, so the macro now appears to be all the paths in my path environment variable followed by '-split ;'. So that's a problem, but only listed here for context. I'll figure that out separately. The purpose of this question (one question per post) is the following:

I was following this and getting something weird...

If I now enter doskey /macros:all I get:


    "envpath=C:\WINDOWS\system32;C:\WINDOWS;<etc>;" -split ;

Please note the quotes.

Now, if, per the above-linked other answer, I enter doskey envpath=something (literally) then doskey /macros:all returns:


    "envpath=C:\WINDOWS\system32;C:\WINDOWS;<etc>;" -split ;
    envpath=something

(which is expected except for the quoted part).

And when I do doskey envpath= it clears/deletes that macro, and doskey /macros:all, returns the first result again.

So my question: What is this entry in the quotes and how do I get rid of that please?

Hopefully I've explained that clearly enough. If confused please feel free to ask for clarification. Thanks in advance for help!

Upvotes: 1

Views: 222

Answers (1)

mklement0
mklement0

Reputation: 438018

As noted in the answer to your related question,

  • it's best to avoid use of doskey.exe in PowerShell, because getting it to work requires forgoing PowerShell's own, rich command-line editing experience, by unloading the PSReadLine module first (Remove-Module PSReadLine) - see this answer for background information.

  • the better alternative is to define a PowerShell function and add it to your $PROFILE file, as shown in the linked answer.


If you want to use doskey.exe nonetheless, define your macro as follows (for PowerShell (Core) 7+, replace powershell.exe with pwsh.exe):

doskey /exename=powershell.exe envpath = `$env:Path -split "';'"
  • The tokens that make up the PowerShell command must be passed as individual arguments to doskey.exe, and be sure to follow the = with a space.

    • If you accidentally pass the PowerShell command as a single, quoted argument, doskey.exe stores enclosing "..." as part of the macro and includes these quotes when it expands the macro.

    • If you additionally also include the macro name in that single, quoted argument, you not only get a virtually unusable macro,[1] you also cannot remove it in-session (neither individually, with doskey /exename=powershell.exe envpath=, nor as part of clearing all macros with Alt-F10) - you must start a new PowerShell session to get rid of it.

      • Note that the macro name is also included if you attempt partial quoting in PowerShell, e.g., doskey envpath="`$env:Path -split ','" is effectively the same as doskey "envpath=`$env:Path -split ','", due to how PowerShell rebuilds the command line behind the scenes (see below).
  • To avoid instant expansion of $env:Path, the $ character is preceded by PowerShell's escape character, the so-called backtick (`).

  • To preserve the '...'-quoting around ;, outer "..." quoting is used.

    • This is necessary, because PowerShell rebuilds the command line behind the scenes when it invokes external programs, which involves translating '...' quoting into "..." quoting if necessary; that is, irrespective of what quoting was originally used on the PowerShell side, an argument is enclosed in "..." if it contains spaces and used unquoted otherwise; thus, ';' by itself would turn into just ; on the behind-the-scenes command line; an originally partially quoted argument that contains spaces ends up being double-quoted as a whole.

[1] In a macro definition that doskey /macros or doskey /macros:all lists as "envpath=C:\WINDOWS\system32;C:\WINDOWS;<etc>;" -split ;, the macro name is "envpath verbatim, i.e. including the opening ". The - then unbalanced - closing " is retained in the text to expanded to.

Upvotes: 0

Related Questions