Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect whether current shell is powershell in python

What's the recommended way to check which shell is my python program running inside? I know I can query os.environ.get('SHELL') for the shell name, but what can I use to determine powershell?

like image 857
Nehal J Wani Avatar asked Apr 09 '19 16:04

Nehal J Wani


People also ask

How do you identify which shell you are using?

If the ps command is run generally in the shell then it simply tells the name of the shell. The first column tells the PID and the last column tells the type of shell i.e. bash. 3) By viewing /etc/passwd file: This tells the feature of the user just like it's name, shell, and ID.

How do I know if PowerShell is running?

How can I tell if I am executing on PowerShell Core? Just use the $PSVersionTable object and examine the PSEdition value. If it returns 'Core' you are running on PowerShell core.

How do I find my current shell on Mac?

There's an easy way to tell — here's how. Open the Terminal application on your Mac. At the prompt, type echo $0 , as shown below.


1 Answers

Generally, environment variable SHELL does not tell you what shell invoked your script, it only tells you the binary path of the current user's default shell (on Unix-like platforms), as chepner notes.

To detect what shell invoked your script, you must examine the script's parent process.

The following works with the psutil package installed (it is both v2- and v3-compatible):

import os, psutil, re

# Get the parent process name.
pprocName = psutil.Process(os.getppid()).name()

# See if it is Windows PowerShell (powershell.exe) or PowerShell Core (pwsh[.exe]):
isPowerShell = bool(re.fullmatch('pwsh|pwsh.exe|powershell.exe', pprocName))

If installing a package is not an option, you can use the following workaround to detect PowerShell specifically, but note the constraints:

  • It presumes a standard PowerShell installation, specifically with respect to environment variable PSModulePath: that is, PSModulePath must either:

    • not be predefined at all outside of PowerShell (Unix-like platforms)
    • or must have just one or two entries outside of PowerShell (Windows, predefined via the registry)[1].
  • It presumes that the script wasn't invoked via nested shell invocations:

    • If you launched a different shell from PowerShell, which then launched your script, the solution below would still indicate that your script was launched by PowerShell.

    • Conversely, if you launched wsl.exe or WSL's bash.exe or MSYS' bash.exe / sh.exe from PowerShell, which then launched your script, the solution below would not indicate that the script was (indirectly) launched by PowerShell, because these executables do not inherit the caller's environment variables; by contrast, the bash.exe / sh.exe that comes with Git and the ones that comes with Cygwin do.

import os

isPowerShell = len(os.getenv('PSModulePath', '').split(os.pathsep)) >= 3 

Note that when PowerShell starts up it ensures that at least 3 locations are present in PSModulePath, on all platforms (the in-box/system-modules location, the all-users location, and the current-user location). As stated, outside of PowerShell the variable isn't predefined at all on Unix, and on Windows it is predefined with at most 2 locations.


[1] Older Windows 10 versions predefined just the system-modules location, $env:SystemRoot\System32\WindowsPowerShell\v1.0\Modules, whereas more recent versions additionally predefine the all-users location, $env:ProgramFiles\WindowsPowerShell\Modules.

like image 61
mklement0 Avatar answered Oct 27 '22 11:10

mklement0