1

How do I get the absolute path to a given binary and store it to a variable?

What is the equivalent to the following for Linux Bash in Windows Powershell?

user@disp985:~$ path=`which gpg`
user@disp985:~$ echo $path
/usr/bin/gpg
user@disp985:~$ 

user@disp985:~$ $path
gpg: keybox '/home/user/.gnupg/pubring.kbx' created
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
gpg: Go ahead and type your message ...

In Windows Powershell, there's Get-Command, but the output is hardly trivial to parse programmatically for a script.

PS C:\Users\user> Get-Command gpg.exe
 
CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Application     gpg.exe                                            2.2.28.... C:\Program Files (x86)\Gpg4win\..\GnuP...
 
 
PS C:\Users\user>

How can I programmatically determine the full path to a given binary in Windows Powershell, store it to a variable, and execute it?

Cyrus
  • 84,225
  • 14
  • 89
  • 153
Michael Altfield
  • 2,083
  • 23
  • 39

1 Answers1

2

For the example command provided by the OP question:

PS C:\Users\user> Get-Command gpg.exe
 
CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Application     gpg.exe                                            2.2.28.... C:\Program Files (x86)\Gpg4win\..\GnuP...
 
 
PS C:\Users\user>

You can extract the "Source" field with the following syntax

PS C:\Users\user> $(Get-Command gpg.exe).Source
C:\Program Files (x86)\Gpg4win\..\GnuPG\bin\gpg.exe

Then you can also store it to a variable and execute it with an ampersand (&) preceding the variable

PS C:\Users\user> $path=$(Get-Command gpg.exe).Source
PS C:\Users\user> echo $path
C:\Program Files (x86)\Gpg4win\..\GnuPG\bin\gpg.exe
PS C:\Users\user> & $path
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
gpg: Go ahead and type your message ...
Michael Altfield
  • 2,083
  • 23
  • 39
  • If `Get-Command` is able to provide an absolute path for `gpg.exe`, then you actually don't need it. You can call it directly with `& gpg.exe` or just `gpg`. – stackprotector Sep 26 '21 at 09:48
  • This question is intentionally general to map `which` usage to the powershell equivalent. However, this is a bad idea in bash because users may override `gpg` with an alias that may yield indeterministic results from scripts. In powershell, my use-case is executing a a binary that exists in many different places on Windows. I want to use a specific path, if possible. Then fall-back on others, if needed and possible. – Michael Altfield Sep 26 '21 at 09:56
  • Nice, but note that `$(...)` is only ever needed in two cases: (a) to embed entire _statement(s)_, notably loops and conditionals, in another statement, and (b) to embed an expression, command, or statement(s) inside `"..."`, an expandable (interpolating) string. Just `(...)` is enough to embed a single _command_ or _expression_ in a statement (and even that isn't needed on the RHS of a _variable assignment_). While not likely, the unnecessary use of `$(...)` can have side effects - see [this answer](https://stackoverflow.com/a/58248195/45375). – mklement0 Sep 26 '21 at 17:29