Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

elevated privileges for a single call

by adalby (Initiate)
on May 06, 2013 at 19:10 UTC ( #1032379=perlquestion: print w/replies, xml ) Need Help??
adalby has asked for the wisdom of the Perl Monks concerning the following question:

I need to find the actual full path of an executing program. The program may be running multiple times concurrently and out of different locations. I need to match each executing instance with its location. Using shell scripts, I can get the pid by ps -eo|grep xxx, and then sudo readlink /proc/$PID/exe. However, I'd really like to code the monitoring in perl, since there are additional perly things I want to do with the info. Is it possible to run the perl script as normal user and only elevate permissions for the readlink() function call?
semi-functional shell script: for PID in $(ps -eo pid,user,lstart,cmd|grep xxx|cut -d" " -f1) do sudo readlink /proc/$PID/exe >>output done
Alternatively, is there a way to find the full path of an executing program?

Replies are listed 'Best First'.
Re: elevated privileges for a single call
by kcott (Chancellor) on May 07, 2013 at 12:27 UTC

    G'day adalby,

    Welcome to the monastery.

    See perlvar for special variables that capture the type of information you're after. Here's a quick example with $^X, $0 and $$:

    $ cat #!/usr/bin/env perl use Cwd qw{abs_path}; print "Perl executing the script: ", `which $^X`; print "Script being executed: ", abs_path($0), "\n"; print "PID: $$\n";
    $ Perl executing the script: /Users/ken/perl5/perlbrew/perls/perl-5.14.2 +_WITH_THREADS/bin/perl Script being executed: /Users/ken/tmp/ PID: 33980

    Variables relating to permissions include: $< (real user id), $> (effective user id), $( (real group id), $) (effective group id).

    The English module provides longer, more meaningful names for these punctuation variables. Don't forget to load it as:

    use English qw{-no_match_vars};

    You might also find perlsec to be useful (even if only for additional examples using these special variables).

    -- Ken

      Thanks, Ken.

      That gives me info on MY executing program. I need info on a different program.

      To be specific, this is part of a script to monitor Oracle databases. Oracle can be installed multiple times on a server in multiple ORACLE_HOMEs. Each home can have zero or more running instances. I am trying to match the instances with the homes. Using the ps system call combined with grep I can find the PIDs of all the running instances. However, the cmd listed is just the basename, not the full path. WHICH doesn't help, since that just tells me the first exe resolved based on my PATH environment variable, not the particular copy that is executing. On Linux, the full path of executing processes are softlinked under /proc/$PID/exe. However, only the process owner and root can resolve the target of that link. I can sudo readlink (as in my script), but to do it in a shell script is ugly and/or AWKward. I would prefer to do it in perl, but I don't know how to sudo the readlink() function call.

Re: elevated privileges for a single call
by pemungkah (Priest) on May 08, 2013 at 22:58 UTC
    I might suggest you use the sudoers file to make readlink executable as root (without a password) by the user(s) who should be running the program. That's simpler, and doesn't require you to fool about with setuid scripts and the like - plus you get logging of when it was used as well.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1032379]
Approved by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2017-06-28 13:17 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (638 votes). Check out past polls.