To be short: How could I execute a
bash -c "set -x; alias ll='ls -l -h'; ll"
?
The output is
alias 'll=ls -l -h'
ll
bash: ll: command not found
Seems bash will add a single quote before my 'll'...
Thanks in advance!
CodePudding user response:
There are two things preventing the alias ll
from being expanded:
Aliases are only expanded in an interactive shell or if you use
shopt -s expand_aliases
.Aliases are expanded (if they are expanded) when the line containing the command is read, not when it is executed, so only aliases defined on previous lines can be expanded. (Also, bash reads an entire compound command before executing it, so you can't define an alias and use it in the same compound command. That doesn't apply here but it might be useful to know.)
So you need to both mark the bash
as interactive and introduce a newline character into the command line. You could, for example, do this:
bash -ic "alias ll='ls -l -h'"$'\n'"ll"
But it would be a lot easier to use a function:
bash -c 'll() { ls -l -h "$@"; }; ll'
All of that is documented in the Bash manual, §6.6 Aliases:
Aliases are not expanded when the shell is not interactive, unless the
expand_aliases
shell option is set usingshopt
……Bash always reads at least one complete line of input, and all lines that make up a compound command, before executing any of the commands on that line or the compound command. 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.
That section ends with the advice to use functions instead:
For almost every purpose, shell functions are preferred over aliases.
CodePudding user response:
To be short:You can't.
According to man bash:
The rules concerning the definition and use of aliases are somewhat confusing. Bash always reads at least one complete line of input, and all lines that make up a compound command, before executing any of the commands on that line or the compound command. 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 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.
For almost every purpose, aliases are superseded by shell functions.
Use functions instead:
bash -c "ll(){ ls -l -h; }; ll"