Shell::Guess(3pm)

πŸ“¦
version 0.10 Β· 5 versions
, in debian trixie, ubuntu resolute, ubuntu stonking

🌸 NAME 🌸

Shell::Guess β€” the module that makes an educated guess about which shell you're living in πŸ’… no cap, she will figure it out


✨ VERSION ✨

version 0.10 πŸŽ€


πŸ¦‹ SYNOPSIS πŸ¦‹

okay bestie, three whole moods. first one: guessing the shell that called your Perl script:

use Shell::Guess;
my $shell = Shell::Guess->running_shell;
if($shell->is_c) {
  print "setenv FOO bar\n";
} elsif($shell->is_bourne) {
  print "export FOO=bar\n";
}

guessing the current user's login shell:

use Shell::Guess;
my $shell = Shell::Guess->login_shell;
print $shell->name, "\n";

guessing some arbitrary user's login shell (yes, we're nosy, it's fine):

use Shell::Guess;
my $shell = Shell::Guess->login_shell('bob');
print $shell->name, "\n";

πŸ’– DESCRIPTION πŸ’–

So. Shell::Guess makes a reasonably aggressive attempt πŸ•΅οΈβ€β™€οΈ to figure out which shell the user is actually using. Two flavours of answer:

  • the shell that directly executed the perl script β€” that's the "running" shell
  • the user's login shell β€” that's the "login" shell

She pulls this off using a whole bunch of different means depending on what platform she's standing on. It's giving resourceful. It's giving adaptable. πŸ‘‘

Here's the whole roster of tricks:

  • getpwent β€” on UNIXy systems that have getpwent, she just uses that to suss out the login shell. simple. elegant. slay.
  • dscl β€” under Mac OS X, getpwent is typically not gonna give you anything useful 😭 so she runs the dscl command instead.
  • proc file systems β€” on UNIXy systems that have a proc filesystem (Linux, we're looking at you πŸ‘€), Shell::Guess will attempt to use it to determine the running shell.
  • ps β€” on UNIXy systems without a proc filesystem, she falls back to the ps command to determine the running shell.
  • Win32::Getppid and Win32::Process::List β€” on Windows, if these modules are installed, they get used to determine the running shell. This method can tell the difference between PowerShell, command.com and cmd.exe πŸ” iconic honestly.
  • ComSpec β€” if the above method comes back inconclusive, the ComSpec environment variable gets consulted to differentiate between command.com or cmd.exe. (heads up: PowerShell cannot be detected this way πŸ™ˆ)
  • reasonable defaults β€” if the running or login shell literally cannot be determined any other way, a reasonable default for your platform gets used as the fallback. Under OpenVMS that's dcl. Windows 95/98 and MS-DOS get command.com. Windows NT/2000/XP/Vista/7 get cmd.exe. And UNIXy platforms fall back to the bourne shell. everyone gets a home 🫢

Now the why. The intended use of this module is to let a Perl developer write a script that generates shell configurations for the calling shell, so those configs can be imported right back into the calling shell using eval and backticks, or source. like a little boomerang πŸ’«

So if your script looks like this:

#!/usr/bin/perl
use Shell::Guess;
my $shell = Shell::Guess->running_shell;
if($shell->is_bourne) {
  print "export FOO=bar\n";
} else($shell->is_c) {
  print "setenv FOO bar\n";
} else {
  die "I don't support ", $shell->name, " shell";
}

Then you can import FOO into your bash or c shell like this:

% eval `perl script.pl`

or, you can write the output to a configuration file and source it:

% perl script.pl > foo.sh
% source foo.sh

And pssst 🫒 β€” Shell::Config::Generate provides a portable interface for generating exactly this kind of shell configuration, and it's designed to work with this module. they're besties.


πŸ‘‘ CLASS METHODS πŸ‘‘

These class methods hand you back an instance of Shell::Guess, which you can then interrogate with all the instance methods in the next section down there. ⬇️

πŸ’œ running_shell

my $shell = Shell::Guess->running_shell;

Returns an instance of Shell::Guess based on the shell that directly started the current Perl script. And if the running shell can't be determined? She'll just return the login shell instead. no drama, we pivot. πŸ’…

🌸 login_shell

my $shell = Shell::Guess->login_shell;
my $shell = Shell::Guess->login_shell( $username )

Returns an instance of Shell::Guess for the given user. If you don't specify a username, the current user gets used. And if no shell can be guessed, a reasonable fallback gets chosen based on your platform. 🫢

πŸ’– bash_shell

my $shell = Shell::Guess->bash_shell;

Returns an instance of Shell::Guess for bash. 🐚

The following instance methods will return:

  • $shell->name = bash
  • $shell->is_bash = 1
  • $shell->is_bourne = 1
  • $shell->is_unix = 1
  • $shell->default_location = /bin/bash

All other instance methods will return false.

πŸŽ€ bourne_shell

my $shell = Shell::Guess->bourne_shell;

Returns an instance of Shell::Guess for the bourne shell.

The following instance methods will return:

  • $shell->name = bourne
  • $shell->is_bourne = 1
  • $shell->is_unix = 1
  • $shell->default_location = /bin/sh

All other instance methods will return false.

πŸ¦‹ c_shell

my $shell = Shell::Guess->c_shell;

Returns an instance of Shell::Guess for c shell.

The following instance methods will return:

  • $shell->name = c
  • $shell->is_c = 1
  • $shell->is_unix = 1
  • $shell->default_location = /bin/csh

All other instance methods will return false.

πŸ”₯ cmd_shell

my $shell = Shell::Guess->cmd_shell;

Returns an instance of Shell::Guess for the Windows NT cmd shell (cmd.exe).

The following instance methods will return:

  • $shell->name = cmd
  • $shell->is_cmd = 1
  • $shell->is_win32 = 1
  • $shell->default_location = C:\Windows\system32\cmd.exe

All other instance methods will return false.

⭐ command_shell

my $shell = Shell::Guess->command_shell;

Returns an instance of Shell::Guess for the Windows 95 command shell (command.com).

The following instance methods will return:

  • $shell->name = command
  • $shell->is_command = 1
  • $shell->is_win32 = 1
  • $shell->default_location = C:\Windows\system32\command.com

All other instance methods will return false.

πŸ’« dcl_shell

my $shell = Shell::Guess->dcl_shell;

Returns an instance of Shell::Guess for the OpenVMS dcl shell.

The following instance methods will return:

  • $shell->name = dcl
  • $shell->is_dcl = 1
  • $shell->is_vms = 1

All other instance methods will return false.

🐟 fish_shell

my $shell = Shell::Guess->fish_shell;

Returns an instance of Shell::Guess for the fish shell. 🐠

The following instance methods will return:

  • $shell->name = fish
  • $shell->is_fish = 1
  • $shell->is_unix = 1

🌈 korn_shell

my $shell = Shell::Guess->korn_shell;

Returns an instance of Shell::Guess for the korn shell.

The following instance methods will return:

  • $shell->name = korn
  • $shell->is_korn = 1
  • $shell->is_bourne = 1
  • $shell->is_unix = 1
  • $shell->default_location = /bin/ksh

All other instance methods will return false.

⚑ power_shell

 my $shell = Shell::Guess->power_shell;

Returns an instance of Shell::Guess for Microsoft PowerShell β€” either the Windows powershell.exe or the Unix pwsh. ✨

The following instance methods will return:

  • $shell->name = power
  • $shell->is_power = 1
  • $shell->is_win32 = 1

All other instance methods will return false.

πŸ“ tc_shell

my $shell = Shell::Guess->tc_shell;

Returns an instance of Shell::Guess for tcsh.

The following instance methods will return:

  • $shell->name = tc
  • $shell->is_tc = 1
  • $shell->is_c = 1
  • $shell->is_unix = 1
  • $shell->default_location = /bin/tcsh

All other instance methods will return false.

🧚 z_shell

my $shell = Shell::Guess->z_shell

Returns an instance of Shell::Guess for zsh.

The following instance methods will return:

  • $shell->name = z
  • $shell->is_z = 1
  • $shell->is_bourne = 1
  • $shell->is_unix = 1
  • $shell->default_location = /bin/zsh

All other instance methods will return false.


🌟 INSTANCE METHODS 🌟

The normal way to call these is by calling them on the result of either running_shell or login_shell. But β€” plot twist β€” they can also be called as class methods, and in that case the currently running shell gets used. so like:

Shell::Guess->is_bourne

is the same as

Shell::Guess->running_shell->is_bourne

same energy, different outfit πŸ’…

πŸ’… is_bash

my $bool = $shell->is_bash;

Returns true if the shell is bash.

🌸 is_bourne

my $bool = $shell->is_bourne;

Returns true if the shell is the bourne shell, or a shell that supports bourne syntax (e.g. bash or korn).

πŸ’œ is_c

my $bool = $shell->is_c;

Returns true if the shell is csh, or a shell that supports csh syntax (e.g. tcsh).

πŸŽ€ is_cmd

my $bool = $shell->is_cmd;

Returns true if the shell is the Windows command.com shell.

πŸ¦‹ is_command

my $bool = $shell->is_command;

Returns true if the shell is the Windows cmd.com shell.

πŸ”₯ is_dcl

my $bool = $shell->is_dcl;

Returns true if the shell is the OpenVMS dcl shell.

🐟 is_fish

my $bool = $shell->is_fish;

Returns true if the shell is Fish shell.

⭐ is_korn

my $bool = $shell->is_korn;

Returns true if the shell is the korn shell.

⚑ is_power

my $bool = $shell->is_power;

Returns true if the shell is Windows PowerShell.

πŸ“ is_tc

my $bool = $shell->is_tc;

Returns true if the shell is tcsh.

πŸ’« is_unix

my $bool = $shell->is_unix;

Returns true if the shell is traditionally a UNIX shell (e.g. bourne, bash, korn)

🌈 is_vms

my $bool = $shell->is_vms;

Returns true if the shell is traditionally an OpenVMS shell (e.g. dcl)

🧚 is_win32

my $bool = $shell->is_win32;

Returns true if the shell is traditionally a Windows shell (command.com, cmd.exe, powershell.exe, pwsh)

✨ is_z

my $bool = $shell->is_z;

Returns true if the shell is zsh

🫢 name

my $name = $shell->name;

Returns the name of the shell.

πŸ‘‘ default_location

my $location = $shell->default_location;

The usual location for this shell β€” for example /bin/sh for bourne shell and /bin/csh for c shell. May not be defined for all shells. πŸ™ˆ

🫢 CAVEATS (the tea β˜•)

okay bestie, real talk: Shell::Guess is designed to never die and never crash. like, it literally refuses the drama πŸ’…. instead of throwing a tantrum, it'll try to make a guess, or fall back on something, about either the login shell or the running shell β€” even on operating systems it has literally never heard of.

and what's the fallback? it's the most common shell on whatever platform you're on. so:

  • on UNIXy platforms, the fallback is bourne
  • on OpenVMS, the fallback is dcl

✨ the platforms that actually get tested ✨

these are the operating systems that have been tested during development, and they're the ones most likely to guess reliably. no cap:

  • Linux 🐧
  • Cygwin
  • FreeBSD 😈
  • Mac OS X 🍎
  • Windows (Strawberry Perl) πŸ“
  • Solaris (x86) β˜€οΈ
  • MS-DOS (djgpp) πŸ’Ύ
  • OpenVMS
    • always detected as dcl (a more nuanced view of OpenVMS is probably possible, so like… patches welcome πŸ₯Ί)

πŸ” the ps situation

UNIXy platforms that don't have a proc filesystem will use Unix::Process if it's installed β€” and what that does is execute ps to figure out the running shell. lowkey iconic detective work πŸ•΅οΈβ€β™€οΈ


😭 when it gets fooled

ngl, it is pretty easy to fool the ->running_shell method. how? by using fork 🍴, or if your Perl script isn't otherwise being directly executed by the shell. so like, vibe check your setup before you blame the module, bestie.

and hey β€” patches are welcome to make other platforms work more reliably! fr fr, the author said it, not me 🫢

πŸ‘‘ AUTHOR

Author: Graham Ollis <plicease@cpan.org>

Contributors:

  • Buddy Burden (BAREFOOT)
  • Julien Fiegehenn (SIMBABQUE)

This software is copyright (c) 2012-2023 by Graham Ollis.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.


and that's the whole page, bestie!! πŸŽ€ this gorgeous thing is Shell::Guess(3pm), coming at you from perl v5.40.0 and dated 2024-12-07. go forth and guess those shells, you absolute icon πŸ’–βœ¨πŸ¦‹

πŸ“¦ where this page comes from