record every backtick on STDOUT or some log file

Discussion in 'Perl Misc' started by perlnewbie, Apr 23, 2012.

  1. perlnewbie

    perlnewbie Guest

    Hi,

    I got a Perl script from my colleague which I am going to run on my server.

    This script is written to setup some folder structure and to create some users/group/permission/ownership. So, most part of the script uses backtick to call OS commands with some logic behind it. (my question is not about whether backtick is good or bad).

    I want to make a minimum changes to the script so that every backtick with variable interpolation (example: `cd $v` should be recorded as 'cd /var/tmp', same as executed by OS) is recorded on STDOUT/STDERR or to some log file..

    I don't want to go and add print statement just before every backticks.

    What should be the good minimum change (either internal change or thru somewrapper) with or without any modules would help my scenario?

    I am looking for a summary of chmod, chown, mkdir OS commands executed by this perl script.

    Thanks.
    perlnewbie, Apr 23, 2012
    #1
    1. Advertising

  2. perlnewbie

    J. Gleixner Guest

    On 04/23/12 12:42, perlnewbie wrote:
    > Hi,
    >
    > I got a Perl script from my colleague which I am going to run on my server.
    >
    > This script is written to setup some folder structure and to create some users/group/permission/ownership. So, most part of the script uses backtick to call OS commands with some logic behind it. (my question is not about whether backtick is good or bad).
    >


    BTW: Backticks are generally not good, so rewrite it or have your
    colleague rewrite it using the correct Perl functions: chdir,
    chmod, etc..

    > I want to make a minimum changes to the script so that every backtick with variable interpolation (example: `cd $v` should be recorded as 'cd /var/tmp', same as executed by OS) is recorded on STDOUT/STDERR or to some log file.
    >
    > I don't want to go and add print statement just before every backticks.


    That's probably the easiest way to do what you want.

    >
    > What should be the good minimum change (either internal change or thru some wrapper) with or without any modules would help my scenario?


    Could also change them into a sub call:

    e.g.
    `cd $v`;

    run( "cd $v" );

    sub run
    {
    my $cmd = shift;

    print "Running: $cmd\n";
    my $out = `$cmd`;
    print "Output: $out\n";
    }
    J. Gleixner, Apr 23, 2012
    #2
    1. Advertising

  3. perlnewbie

    Tim McDaniel Guest

    In article <4f959dee$0$75671$>,
    J. Gleixner <> wrote:
    >BTW: Backticks are generally not good, so rewrite it or have your
    >colleague rewrite it using the correct Perl functions: chdir,
    >chmod, etc..


    Opinions may differ. I think that one should use tools that are
    well-suited for the work. Personally, if the shell can do it
    perfectly well, I'm as inclined to use the shell as not, especially if
    it's useful that it affect only itself and not the Perl program.
    E.g., maybe I want a bit of script to "cd '$dir' && munge foo.cfg
    out.ppp" but I want the Perl program to stay where it is.

    But I may be atypical, because I know how to do bullet-resistant
    shell coding. It *is* harder to do; much easier to have

    mkdir($dir,0777) or crash("my_mkdir: mkdir '$dir' failed: $!");

    or use autodie (I think it is).

    >Could also change them into a sub call:


    I recommend that. I usually call it my_system. I usually have it
    echo the final command line, and have a global debug boolean that
    makes it only do the output without running it, and analyze $? and $!
    and such. Maybe I have a log. The advantage of a sub is that you can
    do anything.

    I see that once I did

    use English;

    # Borrowed from the perlipc man page.
    sub kidopen($@) {
    my ($dir, @cmd) = @_;
    my $pid;
    my $sleep_count = 0;
    if ($dir eq '<') {
    $dir = '-|';
    } elsif ($dir eq '>') {
    $dir = '|-';
    } else {
    die "$0: internal: kidopen() has invalid direction $dir, ";
    }
    if ($dir eq '|-') {
    open(KID, '|less');
    return;
    }
    for (;;) {
    $pid = open(KID, $dir);
    last if defined $pid;
    warn "$0: Cannot fork a child: $!\n";
    die "$0: Too many attempts failed. Dying.\n"
    if $sleep_count++ > 6;
    sleep 10;
    }

    if ($pid) { # parent
    # Return to caller to do something interesting.
    } else { # child
    exec @cmd or
    die("$0: Cannot exec program: $!.\n",
    " Program: @cmd");
    # NOTREACHED
    }
    }

    sub kidclose() {
    $ERRNO = 0;
    # print STDERR "=== DEBUG in kidclose\n";
    close(KID) or
    warn("$0: Child exited with code $CHILD_ERROR, ",
    "errno ", 0+$ERRNO, ": $ERRNO.\n");
    # print STDERR "=== DEBUG done in kidclose\n";
    }

    The advantage is that "exec @cmd" means that it will NOT be subject to
    the vagarities of shell parsing, which is great if you have one
    program with possible unusual arguments that you want not to be
    violated by the shell, but really lousy if you want
    cd $dir && cp * /scratch/wav

    --
    Tim McDaniel,
    Tim McDaniel, Apr 23, 2012
    #3
  4. (Tim McDaniel) writes:
    > In article <4f959dee$0$75671$>,
    > J. Gleixner <> wrote:
    >>BTW: Backticks are generally not good, so rewrite it or have your
    >>colleague rewrite it using the correct Perl functions: chdir,
    >>chmod, etc..

    >
    > Opinions may differ. I think that one should use tools that are
    > well-suited for the work. Personally, if the shell can do it
    > perfectly well, I'm as inclined to use the shell as not, especially if
    > it's useful that it affect only itself and not the Perl program.
    > E.g., maybe I want a bit of script to "cd '$dir' && munge foo.cfg
    > out.ppp" but I want the Perl program to stay where it is.


    Perl supports fork. Also, when using the Perl functions, it is
    possible to implement real error handling because the actual system
    error codes are available.
    Rainer Weikusat, Apr 23, 2012
    #4
  5. perlnewbie

    Tim McDaniel Guest

    In article <>,
    Rainer Weikusat <> wrote:
    > (Tim McDaniel) writes:
    >> In article <4f959dee$0$75671$>,
    >> J. Gleixner <> wrote:
    >>>BTW: Backticks are generally not good, so rewrite it or have your
    >>>colleague rewrite it using the correct Perl functions: chdir,
    >>>chmod, etc..

    >>
    >> Opinions may differ. I think that one should use tools that are
    >> well-suited for the work. Personally, if the shell can do it
    >> perfectly well, I'm as inclined to use the shell as not, especially if
    >> it's useful that it affect only itself and not the Perl program.
    >> E.g., maybe I want a bit of script to "cd '$dir' && munge foo.cfg
    >> out.ppp" but I want the Perl program to stay where it is.

    >
    >Perl supports fork.


    Quite so, but doing so reliably and well takes some effort, as shown
    by "man perlipc".

    >Also, when using the Perl functions, it is possible to implement real
    >error handling because the actual system error codes are available.


    Except that programs generally do their own error checking on their
    own pretty well, like for "mv afile /unwritable", but you have to
    implement that in Perl on your own, so that's actually an argument
    *against* doing it in Perl.

    Except, as I noted, if you're trying to do sophisticated quoting or
    control in shell. It takes some knowledge and effort to do
    bullet-resistant programming in either shell or Perl, and
    unfortunately the skills needed for one often don't translate to the
    other.

    --
    Tim McDaniel,
    Tim McDaniel, Apr 23, 2012
    #5
  6. (Tim McDaniel) writes:
    > Rainer Weikusat <> wrote:
    >> (Tim McDaniel) writes:


    [...]

    >>> if the shell can do it perfectly well, I'm as inclined to use the
    >>> shell as not, especially if it's useful that it affect only itself
    >>> and not the Perl program. E.g., maybe I want a bit of script to
    >>> "cd '$dir' && munge foo.cfg out.ppp" but I want the Perl program
    >>> to stay where it is.

    >>
    >>Perl supports fork.

    >
    > Quite so, but doing so reliably and well takes some effort, as shown
    > by "man perlipc".


    perlipc essentially only mentions fork as part of a daemonization
    procedure. But that's not what you get with backticks. These just
    instruct perl to fork, exec the shell and pass the command in
    backticks as argument to it in a suitable way (which then causes the
    shell to fork and exec the actual command, with the shell waiting for
    the command and perl waiting for the shell. And any 'result' is only
    available as text which needs to be interpreted/ parsed to get at the
    actual data). And you can as well just fork the perl process and
    execute the system calls changing the process state directly without
    affecting the state of the parent process.

    >>Also, when using the Perl functions, it is possible to implement real
    >>error handling because the actual system error codes are available.

    >
    > Except that programs generally do their own error checking on their
    > own pretty well, like for "mv afile /unwritable", but you have to
    > implement that in Perl on your own, so that's actually an argument
    > *against* doing it in Perl.


    Minus output, the only result information perl gets from an external
    command is generally "it worked" or "it failed" no matter what that
    external command might have done. And this essentially makes it
    impossible to implement an _error handling strategies_ in Perl.
    Rainer Weikusat, Apr 23, 2012
    #6
  7. perlnewbie

    Tim McDaniel Guest

    In article <>,
    Rainer Weikusat <> wrote:
    > (Tim McDaniel) writes:
    >> Rainer Weikusat <> wrote:
    >>>Perl supports fork.

    >>
    >> Quite so, but doing so reliably and well takes some effort, as shown
    >> by "man perlipc".

    >
    >perlipc essentially only mentions fork as part of a daemonization
    >procedure.


    perlipc in 5.8.8 mentions safe implementations of pipe open (which has
    a fork implicitly behind the scenes) and backtick, defining "safe" as
    "you can do it without the shell getting its grubby fingerprints on
    the arguments".

    To be fair, though, my Perl scripts don't usually have a problem with
    chdir and such, so that aspect of using shell commands is not often of
    use.

    >>>Also, when using the Perl functions, it is possible to implement real
    >>>error handling because the actual system error codes are available.

    >>
    >> Except that programs generally do their own error checking on their
    >> own pretty well, like for "mv afile /unwritable", but you have to
    >> implement that in Perl on your own, so that's actually an argument
    >> *against* doing it in Perl.

    >
    >Minus output, the only result information perl gets from an external
    >command is generally "it worked" or "it failed" no matter what that
    >external command might have done. And this essentially makes it
    >impossible to implement an _error handling strategies_ in Perl.


    In practice, "it worked || it failed" has been good enough for me so
    far. The shell programs I've called have been good enough about
    reporting their errors for me to realize the underlying problem, and I
    can't think of anything different to do depending on which failure
    happened.

    I'm not saying you're wrong, mind you. If you want to do a mkdir and
    need to do different things based on which error happened, or you need
    efficiency, then you have to call Perl's mkdir and look at the error
    status. It's just that, for me, I haven't needed either, and
    therefore things like
    system('mkdir', '-p', $tmpdir) or die "cannot create '$tmpdir'.\n";
    work for my purposes.

    And I certainly don't want to re-implement
    system('rm', '-rf', $dir) or die ...
    in Perl.

    --
    Tim McDaniel,
    Tim McDaniel, Apr 23, 2012
    #7
  8. (Tim McDaniel) writes:
    > In article <>,
    > Rainer Weikusat <> wrote:
    >> (Tim McDaniel) writes:
    >>> Rainer Weikusat <> wrote:
    >>>>Perl supports fork.
    >>>
    >>> Quite so, but doing so reliably and well takes some effort, as shown
    >>> by "man perlipc".

    >>
    >>perlipc essentially only mentions fork as part of a daemonization
    >>procedure.

    >
    > perlipc in 5.8.8 mentions safe implementations of pipe open (which has
    > a fork implicitly behind the scenes) and backtick, defining "safe" as
    > "you can do it without the shell getting its grubby fingerprints on
    > the arguments".


    That's obviously not relevant in the context of 'executing system
    calls which change the state of a process without affecting the state
    of "the process which caused that"'. Invoking the safely shell with
    input data from untrusted sources "takes some effort" but that's
    besides the point.

    [...]

    > And I certainly don't want to re-implement
    > system('rm', '-rf', $dir) or die ...
    > in Perl.


    That's not particularly difficult and I've probably done so a couple
    of times: If I can get by writing a shell scripts, I'll write a shell
    script.
    Rainer Weikusat, Apr 24, 2012
    #8
  9. perlnewbie

    Chris Davies Guest

    perlnewbie <> wrote:
    > example: `cd $v` should be recorded as 'cd /var/tmp', same as executed
    > by OS


    You are aware that `cd $v` (for any value of $v) is a meaningless
    operation on a UNIX/Linux type system?

    Chris
    Chris Davies, Apr 25, 2012
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Leszek Dubiel
    Replies:
    3
    Views:
    9,801
  2. Carl Banks

    Backtick Virgins

    Carl Banks, Aug 21, 2003, in forum: Python
    Replies:
    1
    Views:
    327
    Peter Hansen
    Aug 21, 2003
  3. Mike
    Replies:
    7
    Views:
    577
  4. =?Utf-8?B?SXJ3YW5zeWFo?=
    Replies:
    4
    Views:
    2,449
    =?Utf-8?B?SXJ3YW5zeWFo?=
    Oct 30, 2007
  5. Replies:
    4
    Views:
    413
Loading...

Share This Page