zentara has asked for the wisdom of the Perl Monks concerning the following question:

Someone asked an interesting question in comp.lang.perl.tk today, about how to get a list of all bash shell aliases for the current user.

It went like this:

n my perl script, I need to know the command alias name to make my program flexible. I tried many methods like system("alias cmd"), `alias cmd`, use shell qw,etc. But no one could recognize the built in command alias. If I use `which cmd`, it would look for the command based on environmental PATH and skip the alias information. Finally, I found a useful document from Shell - perldoc.perl.org. It says "It isn't possible to call shell built in commands, but it can be done by using a workaround, e.g. shell( '-c', 'set' )." Does anyone know how to implement the work around method "shell( '-c', 'set' )" or any possible method to get command alias information? I'm really exhausted for this problem. Please give me a hand.

Well I started to play around, and found a way, but I was wondering if this is the best that can be done. The basic problem is that when running the IPC, the OUT filehandle would never close, requiring me to wrap the while (sysread, OUT, 512) loop in an eval to time it out. Otherwise, the script will just sit in the loop until you control-c. This hack is pretty bad, involving a goto and an eval, but it works. Is there any other way to break out of the hanging sysread?

#!/usr/bin/perl use warnings; use strict; use IPC::Open3; $|=1; my $pid=open3(\*IN,\*OUT,\*ERR,'/bin/bash -i'); my $cmd = 'builtin alias'; #send cmd to bash print IN "$cmd\n"; my $result_err = <ERR>; print "ERR->$result_err\n"; my @aliases; my $buf; my $timeout = 1; #after 1 seconds no bash output, script continues eval{ local $SIG{ALRM} = sub { goto END }; alarm $timeout; while( sysread(OUT, $buf, 512)){ #print $buf; push @aliases,$buf; } alarm 0; }; END: print "@aliases\n";

I'm not really a human, but I play one on earth. Cogito ergo sum a bum

Replies are listed 'Best First'.
Re: getting a list of your bash aliases
by almut (Canon) on Apr 28, 2008 at 19:30 UTC

    You could try "builtin alias; exit" as the command (works for me).

Re: getting a list of your bash aliases
by FunkyMonk (Bishop) on Apr 28, 2008 at 20:03 UTC
    Backticks worked for me (tho I actually used qx{}). Some filtering (with grep) was needed because my .bashrc outputs some other messages, and -i to force an interactive shell. You can't use sh as that doesn't read .bashrc.
    print grep /^alias/, qx{/bin/bash -ic alias}; __END__ alias e='emacs' alias grep='grep --colour=auto' #etc

    but that's only going to list the aliases defined by sourcing .bashrc, not the aliases in effect when the script was called. You can decide whether that's important or not.


    Unless I state otherwise, my code all runs with strict and warnings
Re: getting a list of your bash aliases
by pc88mxer (Vicar) on Apr 28, 2008 at 22:52 UTC
    Your timeout problem is very similar to what was discussed in Eval leaving zombies when dying with alarm. If you don't want to use SIGALRM, there's an approach based on IO::Select - see that thread for more details.

    Another issue I see is that you should close STDIN to the bash process after sending the command:

    print IN "$cmd\n"; close(IN);
    Then bash should exit on its own.
Re: getting a list of your bash aliases
by starbolin (Hermit) on Apr 28, 2008 at 23:27 UTC

    I think the OP ( not you zentara the original OP ) was confused as to the command he wanted. He seemed to want to say something like "builtin cmd" because he said he tried "which cmd". Instead he was trying "alias cmd" which, of course, returned nothing. The rest of the post and zentara's reply the go about solving a problem that was caused by the OP's misunderstanding and not by the shell.


    s//----->\t/;$~="JAPH";s//\r<$~~/;{s|~$~-|-~$~|||s |-$~~|$~~-|||s,<$~~,<~$~,,s,~$~>,$~~>,, $|=1,select$,,$,,$,,1e-1;print;redo}