How to get at the perl options

S

sharma__r

Hi,

Is there a way to capture the perl options in a command like this:
perl -w -S script.pl

@ARGV holds the options script.pl & onwards. What I want are the the
perl options (in this case:
-w, -S ) also.
 
U

Uri Guttman

BM> Quoth (e-mail address removed):
BM> Some of them (like -w) show up as magic variables: see perldoc perlvar.
BM> I don't believe that applies to -S.

and a better question is why do you want them? i have never seen anyone
ask for these in 16 years of hacking perl. what purpose could you have
to want this info? those are options to make perl do certain things and
there are plenty of them. also perl can use environment variables to set
some things that options can also do. you can't tell where the settings
came from. i smell a major XY problem here where your real problem is X
but you are asking about your solution which is Y.

uri
 
I

Ilya Zakharevich

BM> Some of them (like -w) show up as magic variables: see perldoc perlvar.
BM> I don't believe that applies to -S.

and a better question is why do you want them? i have never seen anyone
ask for these in 16 years of hacking perl.

I need them very much. See the ugly hacks done in perl debugger to
implement even the brain-damaged version of `R' command.

Getting "the @wholeARGV" would be very useful in many situations...
As the minimum, consider remote debugging scenario...

Yours,
Ilya
 
U

Uri Guttman

BM> Some of them (like -w) show up as magic variables: see perldoc perlvar.
BM> I don't believe that applies to -S.
IZ> I need them very much. See the ugly hacks done in perl debugger to
IZ> implement even the brain-damaged version of `R' command.

IZ> Getting "the @wholeARGV" would be very useful in many situations...
IZ> As the minimum, consider remote debugging scenario...

trivial then. write a c (or other lang wrapper), grab all the argv, then
call perl and pass argv to it. but it makes little sense for needing all
of the options when some apply to perl and some apply to your app. if
you want that control, do the above. i leave it as an exercise to the
reader.

uri
 
S

sharma__r

  BM> Quoth (e-mail address removed):
  >>
  >> Is there a way to capture the perl options in a command like this:
  >> perl -w -S script.pl
  >>
  >> @ARGV holds the options script.pl & onwards. What I want are the the
  >> perl options (in this case:
  >> -w, -S ) also.

  BM> Some of them (like -w) show up as magic variables: see perldoc perlvar.
  BM> I don't believe that applies to -S.

and a better question is why do you want them? i have never seen anyone
ask for these in 16 years of hacking perl. what purpose could you have
to want this info? those are options to make perl do certain things and
there are plenty of them. also perl can use environment variables to set
some things that options can also do. you can't tell where the settings
came from. i smell a major XY problem here where your real problem is X
but you are asking about your solution which is Y.

uri

The problem that I am facing is the following: I have a perl script
(run_Calibre_Command.plx)
which i want to ensure that everybody in our team pick the identical
versions of
"perl" irrespective of his .cshrc/.tcshrc settings. Towards that end,
we use the famous
eval 'exec perl -w -S -- "$0" ${1+"$@"}'
if 0;
dictum copied from the Camel book.
But I have modified that a little & it looks somewhat like this:

:
eval '
PATH=/tool/all/wrappers/bin${PATH:+:}${PATH-}; export PATH
_perl_wrapper="5.8.8/2007"; export _perl_wrapper
exec perl -w -S -- "$0" ${1+"$@"}
'
if 0;

use strict;
use warnings;

local $\ = "\n";
......
......

__END__

Now what is happening is that if I invoke the perl script from the
command line as:
% run_Calibre_Command.plx [script options follow here]

Then whoever uses it gets to invoke the same version of perl.
However, if I were to invoke the perl script from the command line as:
% perl [perl options] run_Calibre_Command.plx [script options
follow here]

then the eval 'exec perl ...' scheme breaks down since depending on
the user's
..cshrc/.tcshrc settings that particular version of perl binary & it's
attendant
library files get invoked. To overcome this I wrote a brief code
inside the BEGIN
block that does esentially what the eval 'exec ...' is doing.

BEGIN{
$ENV{PATH} = "/tool/all/wrappers/bin:$ENV{PATH}"
unless $ENV{PATH} =~ m{\A/tool/all/wrappers/bin[:]}xms;

if ( !exists $ENV{_perl_wrapper} || !defined $ENV{_perl_wrapper} ||
$ENV{_perl_wrapper} ne '5.8.8/2007' ) {
local ($", $\) = (" ", "\n");
print {*STDERR} "realigning perl path...";
$ENV{_perl_wrapper} = '5.8.8/2007';
exec("PATH=$ENV{PATH} _perl_wrapper=$ENV{_perl_wrapper} perl -w -
S \"@ARGV\" -- $0"); # <======== PROBLEM HERE
}
}
##################################

As you can see we are not able to capture the perl options using this
way as @ARGV just looks at the perl script options
not the options to perl.


In essence I just want to re-fire the perl command line as is, but
with the new perl binary.

% perl [perl options] run_Calibre_Command.plx [script options]

How would we do it, if at all it's feasible

-- Rakesh
 
M

Marc Girod

How would we do it, if at all it's feasible

Check that the intended perl is used, and die if not with instructions
to the user.

Is this too simple?

Marc
 
S

sharma__r

Check that the intended perl is used, and die if not with instructions
to the user.

Is this too simple?

Marc

But I dont want "perl" to die. I want it to go on thru run with the
appropriate version.

--Rakesh
 
J

Jens Thoms Toerring

But I dont want "perl" to die. I want it to go on thru run with the
appropriate version.

But if you depend on a certain version of Perl and the user
started a different version then this "bad" version is al-
ready running and nothing will be able to magically change
it to the desired version by setting or unsetting some
flags. Or am I misunderstanding sonething badly?

If you definitely have to use a certain version of Perl but
the user may start a different one the only way I can think
of at short notice is to check for the version and if it's
the "wrong" one to exec() the correct one from within your
script (perhaps within a BEGIN block). Before doing so you
could also clean up the environment to suite your needs and
then start the correct version wih whatever flags/options
you want.
Regards, Jens
 
S

sharma__r

But if you depend on a certain version of Perl and the user
started a different version then this "bad" version is al-
ready running and nothing will be able to magically change
it to the desired version by setting or unsetting some
flags. Or am I misunderstanding sonething badly?

If you definitely have to use a certain version of Perl but
the user may start a different one the only way I can think
of at short notice is to check for the version and if it's
the "wrong" one to exec() the correct one from within your
script (perhaps within a BEGIN block). Before doing so you
could also clean up the environment to suite your needs and
then start the correct version wih whatever flags/options
you want.
                          Regards, Jens



You have exactly understood what I'm trying to accomplish,
and if u scroll above in one of replies in this thread, I
mention just this BEGIN-block exec-ing of perl. But, I have
no way of knowing what options were used by perl when
it was fired the first time :-(

Regards,
Rakesh
 
U

Uri Guttman

sr> But I dont want "perl" to die. I want it to go on thru run with the
sr> appropriate version.

then write a short wrapper script (in shell or c or even perl) to
call/exec perl and the script. don't do this in perl itself or you run
into your problem. if you split this into two things it becomes easy.

uri
 
A

Andrew DeFaria

body { font: Helvetica, Arial, sans-serif; } p { font: Helvetica, Arial, sans-serif; } ..standout { font-family: verdana, arial, sans-serif; font-size: 12px; color: #993333; line-height: 13px; font-weight: bold; margin-bottom: 10px; } ..code { border-top: 1px solid #ddd; border-left: 1px solid #ddd; border-right: 2px solid #000; border-bottom: 2px solid #000; padding: 10px; margin-top: 5px; margin-left: 5%; margin-right: 5%; background: #ffffea; color: black; -moz-border-radius: 10px; } ..codedark { border-top: 10px solid #03f; border-left: 1px solid #ddd; border-right: 2px solid grey; border-bottom: 2px solid grey; padding: 10px; margin-top: 5px; margin-left: 5%; margin-right: 5%; background: black; color: yellow; -moz-border-radius: 10px; } #code { color: black; font-size: 14px; font-family: courier; padding-left: 5px; } #line-number { color: #804000; font-family: Arial; font-size: 14px; padding-right: 5px; border-right: 1px dotted #804000; } blockquote[type=cite] { padding: 0em .5em .5em .5em !important; border-right: 2px solid blue !important; border-left: 2px solid blue !important; } blockquote[type=cite] blockquote[type=cite] { border-right: 2px solid maroon !important; border-left: 2px solid maroon !important; } blockquote[type=cite] blockquote[type=cite] blockquote[type=cite] { border-right: 2px solid teal !important; border-left: 2px solid teal !important; } blockquote[type=cite] blockquote[type=cite] blockquote[type=cite] blockquote[type=cite] { border-right: 2px solid purple !important; border-left: 2px solid purple !important; } blockquote[type=cite] blockquote[type=cite] blockquote[type=cite] blockquote[type=cite] blockquote[type=cite] { border-right: 2px solid green !important; border-left: 2px solid green !important; } a:link { color: blue; } a:visited { color: darkblue; } a:hover { color: black; background-color: #ffffcc; text-decoration: underline; } a:active { color: red; } On 11/20/2009 09:46 AM, [email protected] wrote:
You have exactly understood what I'm trying to accomplish, and if u scroll above in one of replies in this thread, I mention just this BEGIN-block exec-ing of perl. But, I have no way of knowing what options were used by perl when it was fired the first time :-(
If your script requires a certain environment then make it so! Don't bother checking what options the user specify - simply invoke your Perl your way.

BTW "you" is spelled with 3 letters. Don't be lazy!
 
A

Andrew DeFaria

body { font: Helvetica, Arial, sans-serif; } p { font: Helvetica, Arial, sans-serif; } ..standout { font-family: verdana, arial, sans-serif; font-size: 12px; color: #993333; line-height: 13px; font-weight: bold; margin-bottom: 10px; } ..code { border-top: 1px solid #ddd; border-left: 1px solid #ddd; border-right: 2px solid #000; border-bottom: 2px solid #000; padding: 10px; margin-top: 5px; margin-left: 5%; margin-right: 5%; background: #ffffea; color: black; -moz-border-radius: 10px; } ..codedark { border-top: 10px solid #03f; border-left: 1px solid #ddd; border-right: 2px solid grey; border-bottom: 2px solid grey; padding: 10px; margin-top: 5px; margin-left: 5%; margin-right: 5%; background: black; color: yellow; -moz-border-radius: 10px; } #code { color: black; font-size: 14px; font-family: courier; padding-left: 5px; } #line-number { color: #804000; font-family: Arial; font-size: 14px; padding-right: 5px; border-right: 1px dotted #804000; } blockquote[type=cite] { padding: 0em .5em .5em .5em !important; border-right: 2px solid blue !important; border-left: 2px solid blue !important; } blockquote[type=cite] blockquote[type=cite] { border-right: 2px solid maroon !important; border-left: 2px solid maroon !important; } blockquote[type=cite] blockquote[type=cite] blockquote[type=cite] { border-right: 2px solid teal !important; border-left: 2px solid teal !important; } blockquote[type=cite] blockquote[type=cite] blockquote[type=cite] blockquote[type=cite] { border-right: 2px solid purple !important; border-left: 2px solid purple !important; } blockquote[type=cite] blockquote[type=cite] blockquote[type=cite] blockquote[type=cite] blockquote[type=cite] { border-right: 2px solid green !important; border-left: 2px solid green !important; } a:link { color: blue; } a:visited { color: darkblue; } a:hover { color: black; background-color: #ffffcc; text-decoration: underline; } a:active { color: red; } On 11/20/2009 10:14 AM, Uri Guttman wrote:
then write a short wrapper script (in shell or c or even perl) to call/exec perl and the script. don't do this in perl itself or you run into your problem. if you split this into two things it becomes easy.
It follows that if he can't trust the the end user will execute the script with the right version of Perl then he probably can't count on the user to properly execute this wrapper script.
 
C

C.DeRykus

...

then write a short wrapper script (in shell or c or even perl) to
call/exec perl and the script. don't do this in perl itself or you run
into your problem. if you split this into two things it becomes easy.

I'm not sure why it was included in the strawberry distro
but there's an example which could be easily modified:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
//
// wrap perl executable
//
int main (int argc, char* argv[]) {

const char* perl_cmd = "C:/strawberry/perl/bin/perl.orig.exe";
char* perl_args[argc];
int i;
FILE *fp;

// perl_args[0] = argv[0];
// for( int i = 1; i <= argc; i++ ) {

fp = fopen("c:/temp/prog.log", "a");
if (fp == NULL) {
printf("C:/temp/prog.log couldn't be opened...");
exit(1);
}
for( i = 0; i <= argc; i++ ) {
printf("arg %d = %s\n", i, argv );
// perl_args[i+1] = argv;
}
fprintf(fp,"%s was called...\n",argv[1]);
argv[0] = perl_cmd;
fclose(fp);

//return execv( perl_cmd, perl_args );
printf("exec'ing binary %s with arg %s...: %s\n", argv[0],argv
[1] );
return execv( perl_cmd, argv );
}
 
T

Ted Zlatanov

BM> Some of them (like -w) show up as magic variables: see perldoc perlvar.
BM> I don't believe that applies to -S.
IZ> I need them very much. See the ugly hacks done in perl debugger to
IZ> implement even the brain-damaged version of `R' command.

IZ> Getting "the @wholeARGV" would be very useful in many situations...
IZ> As the minimum, consider remote debugging scenario...

UG> trivial then. write a c (or other lang wrapper), grab all the argv, then
UG> call perl and pass argv to it. but it makes little sense for needing all
UG> of the options when some apply to perl and some apply to your app. if
UG> you want that control, do the above. i leave it as an exercise to the
UG> reader.

What's the harm in showing the options to the user? It seems very
sensible to me and should not require a wrapper.

As an example, -d:ptkdb is different from -d. Another example: creating
a shell script that will run the current program exactly as it was
invoked, no tinkering needed.

Ted
 
W

Wanna-Be Sys Admin

Ted said:
BM> Some of them (like -w) show up as magic variables: see perldoc
perlvar. BM> I don't believe that applies to -S.

IZ> I need them very much. See the ugly hacks done in perl debugger
to IZ> implement even the brain-damaged version of `R' command.

IZ> Getting "the @wholeARGV" would be very useful in many
situations... IZ> As the minimum, consider remote debugging
scenario...

UG> trivial then. write a c (or other lang wrapper), grab all the
argv, then UG> call perl and pass argv to it. but it makes little
sense for needing all UG> of the options when some apply to perl and
some apply to your app. if UG> you want that control, do the above. i
leave it as an exercise to the UG> reader.

What's the harm in showing the options to the user? It seems very
sensible to me and should not require a wrapper.

As an example, -d:ptkdb is different from -d. Another example:
creating a shell script that will run the current program exactly as
it was invoked, no tinkering needed.

Ted

I thought the OP was saying they wanted their Perl script to capture the
switches passed on the command line. I.e., if someone ran a command
such as -w -S, that the script could show or log that those switches
were used to run the script. Maybe I had misread their question?
 
I

Ilya Zakharevich

BM> Some of them (like -w) show up as magic variables: see perldoc perlvar.
BM> I don't believe that applies to -S.
IZ> I need them very much. See the ugly hacks done in perl debugger to
IZ> implement even the brain-damaged version of `R' command.
IZ> Getting "the @wholeARGV" would be very useful in many situations...
IZ> As the minimum, consider remote debugging scenario...
trivial then. write a c (or other lang wrapper), grab all the argv, then
call perl and pass argv to it.

Unacceptable. Try to explain this to your grandmother (by phone)
[while you are at that, also direct her to modify the
vendor-supplied-binary-program which calls your perl script so that it
calls the wrapper instead... ;-) ;-( ]
but it makes little sense for needing all of the options when some
apply to perl and some apply to your app.

As (I think) I explained, this makes a very perfect sense to me.

Let me reiterate: somebody reports a die() from your module. It is
from a doll knows which perl script called by doll knows who and doll
knows how. All you have control over is your module.

So you try to modify your die() message to provide more info. You are
stuck since you cannot deduce how Perl was called. (One can try to
use OS support, but it maybe an obscure OS, AND some OSes do not
provide introspection of the whole command line of a process.)

Yours,
Ilya
 
I

Ilya Zakharevich

You have exactly understood what I'm trying to accomplish,
and if u scroll above in one of replies in this thread, I
mention just this BEGIN-block exec-ing of perl. But, I have
no way of knowing what options were used by perl when
it was fired the first time :-(

So it is essentially the same problem I mentioned earlier: one wants
to find a way to RESTART the given invocation of Perl (as `R' command
of debugger tries to do - but does not always).

Yours,
Ilya
 
S

sharma__r

then write a short wrapper script (in shell or c or even perl) to
call/exec perl and the script. don't do this in perl itself or you run
into your problem. if you split this into two things it becomes easy.

I'm not sure why it was included in the strawberry distro
but there's an example which could be easily modified:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
//
//  wrap perl executable
//
int main (int argc, char* argv[]) {

    const char* perl_cmd = "C:/strawberry/perl/bin/perl.orig.exe";
    char* perl_args[argc];
    int i;
    FILE *fp;

    // perl_args[0] = argv[0];
    // for( int i = 1;  i <= argc;  i++ ) {

    fp = fopen("c:/temp/prog.log", "a");
    if (fp == NULL) {
        printf("C:/temp/prog.log couldn't be opened...");
        exit(1);
    }
    for( i = 0;  i <= argc;  i++ ) {
        printf("arg %d = %s\n", i, argv );
        // perl_args[i+1] = argv;
   }
   fprintf(fp,"%s was called...\n",argv[1]);
   argv[0] = perl_cmd;
   fclose(fp);

   //return execv( perl_cmd, perl_args );
   printf("exec'ing binary %s with arg %s...:  %s\n", argv[0],argv
[1] );
   return execv( perl_cmd, argv );

}



This doesn't solve my problem. The scenario when the script gets
executed
by the perl binary, as:

perl [perl options] myScrit.plx [script options]

would still pick the whatever perl version is ordained by
the PATH variable

No amount of wrapper logic would solve this unless there's found a way
to recall what options were provided to perl. We already have @ARGV
for
the the script options.

--Rakesh
 
O

Oliver 'ojo' Bedford

Am Sun, 22 Nov 2009 05:56:03 -0800 schrieb sharma__r:
No amount of wrapper logic would solve this unless there's found a way
to recall what options were provided to perl. We already have @ARGV for
the the script options.

Then you probably have to stick to non-portable ways of getting the
command-line. On Linux you can evaluate /proc/$$/cmdline. On other systems
you could use 'ps'.

Oliver
 
C

C.DeRykus

I'm not sure why it was included in the strawberry distro
but there's an example which could be easily modified:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
//
//  wrap perl executable
//
int main (int argc, char* argv[]) {
    const char* perl_cmd = "C:/strawberry/perl/bin/perl.orig.exe";
    char* perl_args[argc];
    int i;
    FILE *fp;
    // perl_args[0] = argv[0];
    // for( int i = 1;  i <= argc;  i++ ) {
    fp = fopen("c:/temp/prog.log", "a");
    if (fp == NULL) {
        printf("C:/temp/prog.log couldn't be opened...");
        exit(1);
    }
    for( i = 0;  i <= argc;  i++ ) {
        printf("arg %d = %s\n", i, argv );
        // perl_args[i+1] = argv;
   }
   fprintf(fp,"%s was called...\n",argv[1]);
   argv[0] = perl_cmd;
   fclose(fp);

   //return execv( perl_cmd, perl_args );
   printf("exec'ing binary %s with arg %s...:  %s\n", argv[0],argv
[1] );
   return execv( perl_cmd, argv );

This doesn't solve my problem. The scenario when the script gets
executed
by the perl binary, as:

   perl [perl options] myScrit.plx [script options]

would still pick the whatever perl version is ordained by
the PATH variable

No amount of wrapper logic would solve this unless there's found a way
to recall what options were provided to perl. We already have @ARGV
for
the the script options.


Without modifying Perl to provide access to all its
commandline options (which would be useful), there
doesn't appear to be an easy way.

An ugly alternative might be to force the non-standard
invocation to re-specify the perl commandline:

[untested]

BEGIN{
...
if ( !exists $ENV{_perl_wrapper} || !defined ... ) {
print "Sorry, you'll need to re-specify any "
"options you used to invoke perl>";
chomp( my $opts = <> );
...
exec("perl $opts -w -S \"@ARGV\" -- $0"); # ..
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,227
Latest member
Daniella65

Latest Threads

Top