Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute a passed alias inside a function?

Tags:

bash

Background:

I'm trying make a function that runs commands on a set interval because I don't have access to a "watch" program. Simplified to it's most basic from, the function I'm trying to write is runit() { $1; }.

What works:

This works fine and dandy when I pass it things that aren't aliases. For example, runit "ls -l" works fine. I get the full output from the ls -l command.

What doesn't work:

The problem starts when I pass it an alias. For example, setting alias ll="ls -l" then calling runit "ll" will result in -bash: ll: command not found.

Things I have tried:

When I hard-code the alias runit() { ll; }, it works fine and gives me what I expect.


I feel like I might be overlooking something, but I can't quite place my finger on it.
Why would hard-coding the alias work fine, but passing it into the function fail?
Is there a way to accomplish what I'm attempting to do?

like image 336
Mr. Llama Avatar asked Jan 25 '13 17:01

Mr. Llama


People also ask

Can you use alias in shell script?

Aliases are disabled for noninteractive shells (that is, shell scripts). Use the unalias builtin to remove an alias.

Does alias override path?

If a shell is involved, aliases take precedence over $PATH lookups. Of course, later alias definitions can override earlier ones. If no shell is involved or no alias by a given name exists, $PATH lookups happen in the order in which the directories are listed in the variable.

What is an alias function?

The alias keyword replaces the command with the string which might be sets of commands or functions. The alias is defined in the ~/. bashrc or ~/.

Can Bash alias take argument?

Bash users need to understand that alias cannot take arguments and parameters. But we can use functions to take arguments and parameters while using alias commands.


1 Answers

From the bash man page discussion of aliases (emphases mine):

Aliases are expanded when a command is read, not when it is executed. Therefore, an alias definition appearing on the same line as another command does not take effect until the next line of input is read. The commands following the alias definition on that line are not affected by the new alias. This behavior is also an issue when functions are executed. Aliases are expanded when a function definition is read, not when the function is executed, because a function definition is itself a compound command. As a consequence, aliases defined in a function are not available until after that function is executed. To be safe, always put alias definitions on a separate line, and do not use alias in compound commands.

You can observe this effect in functions by using the type command:

$ run_it () { ll; }
$ type run_it

You should see that the body of the function contains a call to ls -l, not ll.

The last sentence of the section on aliases:

For almost every purpose, aliases are superseded by shell functions.

My interpretation of that line is: if you think you want to use an alias, try writing a function first. Don't use an alias unless the function demonstrably fails to do what you need.

like image 87
chepner Avatar answered Oct 14 '22 10:10

chepner