in reply to spawning shell commands with aliases

As Fletch pointed out, shells spawned via system() don't source rc files and thus set no aliases.

If you want them, you would have to parse those rc files (.zshrc, .bashrc, .profile etc) yourself as the respective shell does, then traverse the alias list to resolve nested aliases and use the commands in the form they are aliased as instead of the plain command.

Looks to me like a lot of trouble and error-prone too, as different users/shells have different aliasing gustos, and what use is it to get plain ls invoked as e.g. ls -aFC --color=tty and have to take care of all possible arbitrary ouput of such an ls call?

You're better off just providing the switches to programs you invoke with system() yourself, since then you know what to expect.

--shmem

_($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                              /\_¯/(q    /
----------------------------  \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

Replies are listed 'Best First'.
Re^2: spawning shell commands with aliases
by xafwodahs (Scribe) on Dec 19, 2006 at 19:37 UTC
    I'd like to mention that the "ls -1 a/" example was an overly simplistic example.

    A better example might be:

    > mydiff "cleartool lsprivate -tag view1 | egrep '\.o$|\.oo$|\.so$|\.d$' | xargs cleartool ls -short -dir" "cleartool lsprivate -tag view2 | egrep '\.o$|\.oo$|\.so$|\.d$' | xargs cleartool ls -short -dir"

    I made this up, but it's not totally unreasonable. The only difference between the 2 command lines is the tag name (view1 vs view2). If this were a commonly needed command, it would most likely be turned into an alias (or another script pointed to by that user's path), thus we would have:

    > mydiff "mylist view1" "mylist view2"

    Of course, this all depends on being able to run the @ARGV elements as if they were run directly from the parent shell.

      Better example of why you want this, but this just goes more to prove that you really want to use the facilities of the shell itself.

      You might could kludge something close to what you imagine by snooping $ENV{SHELL} and then really running system( qq{$ENV{SHELL} -c 'source $rc_for_shell{ $ENV{SHELL} } ; $command' } ), but that's at some point going to run afoul of quoting issues (aside from the ones the running user may encounter getting the command in as an argument to your mydiff to begin with). Or you're going to have someone set an alias in their shell and then come bug you because it's not working with your wrapper (because they're just testing something before they put it in their .xrc file, or it's a one off query they only need FIVE MINUTES AGO MY BOSS IS BREATHING DOWN MY NECK WHY DOES YOUR COMMAND NOT WORK YOU'RE GOING TO GET ME FIRED YOU WORTHLESS PIECE OF BUDONG DREN!). Or someone's going to install a new version of tcsh which has spiffy new aliases which live in ~/.tcshrc and . . .

      It's a much saner solution to say, "Zsh, bash, and ksh let you provide a subprocess' output as input to another command like so. If you don't use one of those shells, keep using tempoary files like you've always done; may I also welcome you to the 21st century, and I'd like to apologize if you're personally offended by those insurance commerials.

      I can see three approaches to do this.

      What are the elements of constructs like the one you presented?

      • variable interpolation or expansion
      • quoting and escaping
      • streams
      • pipes

      All these elements you find in perl also. Aliases may be setup with subroutines.

      That said, you could

      • construct a generic way to process pipe read and writes, streaming, variable interpolation and escaping in perl
      • write functions that do alias expansion and construct a command lines suitable to be passed to a shell via open or system
      • or stuff those existing constructs into shell scripts, which can then be invoked from perl.

      It all depends on lazieness, hubris, and impatience... I'd write shell scripts.

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}