Windows “equivalents” for bash backticks in cmd and PowerShell
Posted by jpluimers on 2023/05/17
A while ago, I needed the file information of wsl.exe on one of my Windows systems.
On Linux, I would do something like file `which bash`
where file
will give the file details and which
gets you the full path to bash
.
The file
equivalent on Windows for me is [Wayback/Archive] Sigcheck
– Windows Sysinternals | Microsoft Docs, which is part of [Wayback/Archive] File and Disk Utilities – Windows Sysinternals | Microsoft Docs.
The which
equivalent on Windows for me is [Wayback/Archive] where
| Microsoft Docs.
The separate steps on Windows then are like this:
C:\temp>where wsl.exe C:\Windows\System32\wsl.exe C:\temp>SigCheck C:\Windows\System32\wsl.exe Sigcheck v2.82 - File version and signature viewer Copyright (C) 2004-2021 Mark Russinovich Sysinternals - www.sysinternals.com c:\windows\system32\wsl.exe: Verified: Signed Signing date: 09:24 15/10/2021 Publisher: Microsoft Windows Company: Microsoft Corporation Description: Microsoft Windows Subsystem for Linux Launcher Product: Microsoft« Windows« Operating System Prod version: 10.0.19041.1320 File version: 10.0.19041.1320 (WinBuild.160101.0800) MachineType: 64-bit
cmd
solution
My gut feeling was to use the cmd
command [Wayback/Archive] for
| Microsoft Docs, which has built-in back-tick support. This was indeed the “best” cmd
based solution that came up, for instance in [Wayback/Archive] Batch equivalent of Bash backticks – Stack Overflow (thanks [Wayback/Archive] Michael Burr!):
You can get a similar functionality using
cmd.exe
scripts with thefor /f
command:
for /f "usebackq tokens=*" %%a in (`echo Test`) do my_command %%a
Yeah, it’s kinda non-obvious (to say the least), but it’s what’s there.
See
for /?
for the gory details.
The above command is within a batch file (hence the double %%
). On the cmd command-line, it would become this to get the wsl.exe file information:
for /f "usebackq tokens=*" %f in (`where wsl`) do SigCheck "%f"
PowerShell
solution
Then I remembered it might be easier in PowerShell
, and indeed [Wayback/Archive] Jörg W Mittag (thanks!) not only explains this in [Wayback/Archive] What’s the cmd/PowerShell equivalent of back tick on Bash? – Stack Overflow, but also why:
The PowerShell syntax is based on the POSIX
ksh
syntax (and interestingly not on any of Microsoft’s languages likeCMD.EXE
,VBScript
orVisual Basic for Applications
), so many things work pretty much the same as in Bash. In your case, command substitution is done withecho "Foo $(./print_5_As.rb)"
in both PowerShell and Bash.
Bash still supports the ancient way (backticks), but PowerShell cleaned up the syntax and removed redundant constructs such as the two different command substitution syntaxes.
This frees up the backtick for a different use in PowerShell: in POSIX
ksh
, the backslash is used as escape character, but that would be very painful in PowerShell because the backslash is the traditional path component separator in Windows.So, PowerShell uses the (now unused) backtick for escaping.
The poor-mans approach outside PowerShell
would be this:
PowerShell -Command 'SigCheck "$(where.exe wsl)"'
And from within PowerShell
:
SigCheck "$(where.exe wsl)"
But we can do better, as PowerShell
has a built-in almost equivalent to where
consisting of two parts (as PowerShell
is object-based, whereas cmd
is character based):
- [Wayback/Archive]
Get-Command
(Microsoft.PowerShell.Core) – PowerShell | Microsoft Docs searches for a command, including external commands, returning an information object about the found command. - [Wayback/Archive]
ApplicationInfo
Class (System.Management.Automation) | Microsoft Docs wich has aPath
property with the full path of the found application (it is derived from [Wayback/Archive] CommandInfo Class (System.Management.Automation) | Microsoft Docs which does not have thePath
property).
That combination is for instance explained by [Wayback/Archive] User zdan – Super User (thanks!) in [Wayback/Archive] windows – Equivalent of cmd’s “where” in powershell – Super User:
Use the
Get-Command
commandlet passing it the name of the executable. It populates the Path property of the returned object (of type ApplicationInfo) with the fully resolved path to the executable.
So from within PowerShell
, the command would become either of these:
SigCheck "$((Get-Command wsl).Path)"
or more exact (as it won’t find items like aliases, functions, cmdlet, etc):
SigCheck "$((Get-Command -CommandType Application wsl).Path)"
Queries used
- [Wayback/Archive] backtick in windows like linux – Google Search
- [Wayback/Archive] powershell equivalent of bash backticks – Google Search
–jeroen
Leave a Reply