in reply to
Re^2: How do I test if my Perl script was run using a login vs a non-login shell
in thread How do I test if my Perl script was run using a login vs a non-login shell
Here's a solution I came up with in case it helps someone else:
my $p;
my login_shell = 0;
# NOTE: PERL ARGV[0] does not supply the '-' suffix like in
# C, which would allow us to do a reliable test to check if
# we are running inside a login shell. So we need to guess
# this using some hacks.
# HACK 1
# This is a hack to guess whether we are an interactive
# shell in an SSH session based on the SSH_TTY environment
# variable being set or not.
# NOTE: If people are accessing the system via other
# mechanisms like telnet etc. this won't catch those cases.
# NOTE: OpenSSH's sshd will prefix shell with '-' for
# interactive shells but not for non-interactive shells
# e.g. shells called using -c <command>.
# For the gory details see:
# session.c:void do_child(Session *, const char *);
if ($ENV{'SSH_TTY'}) {
$login_shell = 1;
} # End if.
# HACK 2
# This is a hack to check whether this shell was called via
# su and the shell was a login shell. Get the PID of the
# parent process of current instance of this process.
my $parent_pid = getppid();
}
# Get the executable and args of the parent process.
my $process = "";
my $command = "/bin/ps -eo pid,args";
open(FP, "$command|") || die("$!\n");
while (my $proc_line = <FP>) {
chomp($proc_line);
$proc_line =~ s/^\s+//g;
$proc_line =~ s/\s+$//g;
my ($pid, $cmd, @list) = split(/\s+/, $proc_line);
$cmd = (($p = rindex( $cmd, '/' )) >= 0)
? substr($cmd, $p + 1)
: $cmd;
my $args = '';
foreach (@list)
{
$args .= "$_ ";
}
$args =~ s/\s+$//g;
if ($pid eq $parent_pid)
{
$process = "$cmd $args";
chomp($process);
last;
}
}
close(FP);
# If the parent process was an su command with a login
# shell, then this shell should be a login shell too.
if ($process =~ /^su /) {
if (($process =~ / - /) or
($process =~ / -[A-z]*l[A-z]* /) or
($process =~ / --login /)) {
$login_shell = 1;
}
}