Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Re^2: open with pipe

by afoken (Chancellor)
on Aug 01, 2010 at 07:21 UTC ( [id://852315]=note: print w/replies, xml ) Need Help??


in reply to Re: open with pipe
in thread open with pipe

Simple and innocent looking backticks become a nightmare once you write code for more than one system. Some problems, some general, some with your example:

  • You have to work with an unknown shell. Many shells behave according to POSIX, others don't. You don't know what shell you get. You can't write reliable code this way.
  • You don't know the quoting rules of the shell, because you don't know the shell. You can't reliably quote program name and program arguments. You don't even know WHEN to quote names and arguments. On Windows, things are even worse. You may end passing invalid arguments to the invoked program.
  • You don't know the I/O redirection rules of the shell, because you don't know the shell. < and > are pretty universal, but 2> isn't supported everywhere (e.g. command.com doesn't know that). Don't even think about 2>&1.
  • /proc/cpuinfo is Linux specific. For example, FreeBSD doesn't have /proc/cpuinfo. Don't even think about Windows.
  • cat is called without a path, so you will execute the first cat program found in $ENV{'PATH'}. Maybe you execute /usr/bin/cat, the program that concatenates files and prints them to STDOUT. Maybe you execute /home/evil/hoho/cat, a program that changes the root password and spawns a telnet daemon on port 37331 before pretending to be the innocent /usr/bin/cat. No big problem as long as you invoke that cat as unprivileged user, but when run as root, you loose.
  • There is no cat on a fresh Windows system. A similar command is called type and is a shell built-in. Remember that it has a different behaviour (it adds output lines, both empty and with filenames, when called with more than one argument).
  • There is no need to use cat inside backticks to read a file into a scalar: open my $h,'<','/proc/cpuinfo' or die "Could not read /proc/cpuinfo: $!";my $result=do { local $/=<$h> }; close $h;.
  • Neither is there a need to use cat inside backticks to read a file into an array: open my $h,'<','/proc/cpuinfo' or die "Could not read /proc/cpuinfo: $!";my @result=<$h>; close $h;.

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

Replies are listed 'Best First'.
Re^3: open with pipe
by ikegami (Patriarch) on Aug 01, 2010 at 16:59 UTC

    You have to work with an unknown shell. Many shells behave according to POSIX, others don't. You don't know what shell you get. You can't write reliable code this way.

    It's sh except on Windows, and that's easy to check.

      Sure it's /bin/sh, but what shell do you get there?

      Most Linux systems have a symlink to /bin/bash there, most times giving you a bash v1, v2, v3 or v4. Newer Debian and Ubuntu versions have a symlink to /bin/dash, which is a Debian modified ash. Other Linux distributions symlink to the original ash or the busybox implementation of ash. Some BSDs have ash, others pdksh. Solaris has a bourne shell there. Some Mac OS X versions have a zsh there. Other operating systems have a korn shell as /bin/sh.

      See http://www.in-ulm.de/~mascheck/various/shells/ and the pages linked from there for the ugly details, especially http://www.in-ulm.de/~mascheck/bourne/ for the bourne shell variants, and http://www.in-ulm.de/~mascheck/various/ash/ for the ash family.

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
        Wow! I suppose some of those shells are incompatible with the bourne shell?
Re^3: open with pipe
by dasgar (Priest) on Aug 01, 2010 at 13:50 UTC

    @afoken,

    Thanks for expanding the list of reasons why this is not the best idea of what to do for all cases. I knew there were probably more reasons than I could think of as to why this method could lead to trouble. As I mentioned, I do consider this a "quick and dirty" method because it can lead to lots of problems if you're not careful.

    So far, I've been too lazy to try to figure out how to properly use the IPC::Open3 with proper error trapping. I tried unsuccessfully a few times and then gave up and used back ticks instead. I've also been lucky enough so far to not have been bitten in the rear when I've used back ticks. :D

    Also, I could be wrong, but I believe that some of your cautionary warnings about OS specific commands and syntax would apply to any method in any programming language when trying to call system commands.

    And yes, I probably put up a poor example. Considering it was about 12:30 am in my time zone when I posted, I should have waited until I was thinking more straight.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://852315]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (3)
As of 2025-02-11 09:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found