0

I have 3 aliases. They are named echo1, echo2, echo3

How do i execute all 3 of them as part of a larger command?

$ alias echo1='echo 1'
$ alias echo2='echo 2'
$ alias echo3='echo 3'

$ echo1
1

$ echo2
2

$ echo3
3

$ echo{1..3}
bash: echo1: command not found

$ bash -ic echo{1..3}
echo2: echo1: command not found

$ bash -ic 'echo{1..3}'
bash: echo1: command not found

Solution: based on Kusalananda's answer:

 printf '%s\n' {1..3} | xargs -I {} bash -ic "echo{}"
15
  • 1
    There's an interesting question buried here somewhere, but I can't figure out what you thought that command would do.
    – Wildcard
    Jun 1, 2017 at 0:57
  • I rephrased the question
    – yosefrow
    Jun 1, 2017 at 1:01
  • 1
    What do your aliases do? There is no situation in which this command could possibly work. At the most, you would run one alias with the names of the other two aliases passed as arguments. But it looks like your aliases aren't even defined in the shell you're spawning.
    – Wildcard
    Jun 1, 2017 at 1:09
  • 1
    It appears that alias expansion is performed before brace expansion. This doesn't surprise me, but I don't see it mentioned in man bash, which does surprise me. However, aliases defined in the current shell aren't inherited by child shells, so I wouldn't expect bash -ic aliasname to work regardless of brace expansion.
    – Wildcard
    Jun 1, 2017 at 1:34
  • 1
    As I noted before, alias1 alias2 alias3 would only ever run one alias. So why would you want alias{1..3} to do that anyway? Just run alias1;alias2;alias3. If you want to run multiple aliases with the same arguments, you shouldn't be using aliases; you should be using a single function which encompasses the purposes of all three aliases. See unix.stackexchange.com/q/30925/135943
    – Wildcard
    Jun 1, 2017 at 1:43

4 Answers 4

3

Because of the order of evaluation of things, echo$i would be evaluated to the string echo1 (for i=1) after alias expansion.

To be able to make use of the string as an alias, you need to re-evaluate the resulting string:

for i in 1 2 3; do
    eval "echo$i"
done

If echo1, echo2 and echo3 had been shell functions, then the eval had not been needed (tested in Bash 4.4).

Your attempts with bash -c will not work as the aliases are local to the current shell session.

Your initial thing

echo{1..3}

would result in

echo1 echo2 echo3

Even if echo1 had been expanded to echo 1, the result had been the output of the string

1 echo2 echo3

Personally, depending on what you'd wanted the aliases to actually do, I would have implemented a function:

dothing () {
    printf '%s\n' "$@"
}

... and then called that with

dothing {1..3}

to produce

1
2
3

Of course, that would have been achieved with printf '%s\n' {1..3} directly...

6
  • using the -i flag introduces interactive mode which does simulate a manually opened shell with sourced ~/.bashrc ~/.bash_aliases etc. So bash -ci technically should work. but its irrelevant in this case because even if it did work yould end up with echo1 echo2 echo3 which would pass echo2 and echo3 as parameters to echo1
    – yosefrow
    Jun 1, 2017 at 5:52
  • @yosefrow It still would not allow you to call an alias with echo$i.
    – Kusalananda
    Jun 1, 2017 at 5:55
  • ok i tested this just now bash -ic works fine as long as the alias is define in ~/.bash_aliases and sourced in ~/.bashrc
    – yosefrow
    Jun 1, 2017 at 5:58
  • It follows that if i used eval, i could definitely call echo$i. but a for loop makes the most sense i think
    – yosefrow
    Jun 1, 2017 at 6:00
  • You just gave me a great idea! printf '%s\n' {1..3} | xargs -I {} bash -ci "echo{}"
    – yosefrow
    Jun 4, 2017 at 3:03
0

Why not making another function who execute the aliases?

function execute_all_aliases{
  alias1
  alias2
  alias3
}
2
  • Naming the function "alias" probably isn't the best choice.
    – Jeff Schaller
    Jun 1, 2017 at 10:11
  • @JeffSchaller true. Edited Jun 1, 2017 at 10:13
0

You could always do:

eval echo{1..3}\;

That is tell the shell to evaluate the expansion of that as shell code, that is evaluate:

echo1; echo2; echo3;

Some other variants:

eval echo{1..3}$'\n' # separate with newline instead of ;. Can make a
                     # difference for things like alias echo1='echo x|'
                     # alias echo2='tr x y'

eval echo{1..3}'&&' : # only run the next one if the previous one succeeded
0

Thanks to @Kusalananda I came up with the following solution:

printf '%s\n' {1..3} | xargs -I {} bash -ic "echo{}"

This will achieve the goal of executing n amount of aliases named sequentially with other command parts

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.