1

I have the same task as Print Windows %PATH% with every entry on new line

I have a task: print all entries of %PATH% variable on new line. For example:

C:\Program Files\
C:\Windows
C:\Windows\System32

and so on...

which is achievable by echo %path:;=&echo.% as explained here

And I want to assign it to a command alias using DOSKEY

But the following script is failing for me

DOSKEY list=echo %path:;=&echo.%

Which just prints all of the paths while I'm defining the DOSKEY, and after that, when I try to invoke list command, it just doesn't work.

LPVOID
  • 306
  • 3
  • 17
  • 3
    You have to escape the `&` special character as `^&`, and CMD's first pass environment-variable expansion has to be escaped. In a batch script we can escape `%` by doubling it. On the command line the best we can do is disrupt it by inserting a `^` character after the percent, since there shouldn't be an environment variable named "^path". For example: `doskey list=echo %^path:;=^&echo.%`. – Eryk Sun Apr 20 '19 at 13:38
  • 1
    That said, doskey macros wrap the console's [`AddConsoleAlias`](https://learn.microsoft.com/en-us/windows/console/addconsolealias) function, so they are of limited use. The console (conhost.exe) matches the alias source at the beginning of a processed read, and replaces it with the alias target. The target program (in this case cmd.exe) is not involved at all. Thus doskey macros can't work as real shell commands; we can't pipe to them, and we can't use them in batch scripts. It would be better if you created a "list.bat" batch script in a `PATH` directory. – Eryk Sun Apr 20 '19 at 13:46
  • @eryksun Does this mean that I cannot define a custom command to print all paths, each on separate line, without making a separate batch script? – LPVOID Apr 20 '19 at 14:22
  • 1
    It means you need a batch script if you want to do something like loop over the output. For example, if your command is in "list-path.bat", you can run `for /f "tokens=*" %p in ('list-path') do @echo %p` on the command line. That can't work with a console alias because the console would only match and replace "list-path" as the beginning of a line. Obviously it also can't work from a batch script, because that's reading from a disk file instead of the console. – Eryk Sun Apr 20 '19 at 14:46
  • 1
    Also, console aliases don't work in PowerShell (e.g. `doskey /exename=powershell.exe whichever=whatever`) since it uses a low-level console read instead a processed console read. It's no great loss because PowerShell supports real shell aliases and functions. – Eryk Sun Apr 20 '19 at 14:53

1 Answers1

2

As mentioned by @eryksun you'll need to escape special chars.

Update: And to prevent a premature expanding - will use delayed expansion.

doskey list=cmd /v:on /c "for %p in ("!path:;=" "!") do @echo %~p"

An explanation of how this work: we can't use directly solution with echo ^%path:;=^&echo.^% because it's stored in macros already expanded. To prevent this I've tried to use delayed expansion (the part with cmd /v:on /c). It seemed almost working but without splitting on new lines (adding & for some reason doesn't work with delayed expansion).

Then I started to search a way to split !path! and found a neat trick with replacing ; to " " (double quoted space) ("!path:;=" "!"). This splitting was good enough for a plain for (without /f option). The rest is obvious.

montonero
  • 1,363
  • 10
  • 16
  • It works, but not as I wish it to. It statically substitutes "list" with "echo 1^&echo.2^&echo.3" and so on. Which makes it unusable for my case. For example, if I add new paths to the PATH, then I have to redefine the "list" macro again. Can we overcome this? – LPVOID Apr 22 '19 at 22:26
  • @LPVOID That was a challenge. Updated the answer. – montonero Apr 23 '19 at 08:40
  • It's working great! Thank you so much! :) Could you, please, explain why it works like this? Brief explanation of each term in the above command would be awesome! – LPVOID Apr 23 '19 at 23:19
  • @LPVOID I've added the explanation. Hope it's clear enough. – montonero Apr 24 '19 at 07:53
  • Your answer is really awesome! Thank you so much for your effort. :) – LPVOID Apr 24 '19 at 11:19