0

I want to create an alias, that can be defined on any command and concats | lolcat to it. So far I googled myself to

alias MyCommandName='f(){"$@" | lolcat; unset -f f};f'

but when I test it with dmesg I get no result.

# set dmesg
alias dmesg='f(){"$@" | lolcat; unset -f f};f'
#desired command: dmesg | lolcat
dmesg

In my understanding the alias defines a function f, that is called afterwards. To prevent recursion, the last statement is to unset the function.

EDIT: I stopped at:

    alias MyCommandName='f(){eval "$@ | lolcat"; unset -f f};f' 
    alias MyCommandName='f(){eval "$0 $@ | lolcat"; unset -f f};f'

which does not the trick, because i can't pass the $0 argument into my function. The $0 is always f inside of the function. a generic aliaslias like is NOT possible. :(

NOT A DUPLICATE of this, because I am using ZSH and argument passing is possible according to like 10 other answers like this and this :).

KuSpa
  • 125
  • 5
  • 1
    Aliases don't support arguments. The `$@` there is from the shell's arguments, not the aliases. Just use plain functions instead: `f () { "$@" | lolcat; }` then `f dmesg`. – muru Mar 15 '18 at 11:54
  • Those are aliases that define and call **functions**. And they use proper quoting (single quotes, so that `$@` is not evaluated when you define the alias). Please read those posts again and apply them properly. – muru Mar 15 '18 at 12:24
  • I am sorry, I thought I did, what the posts say, since I am pretty new to zsh programming, I can't 100% confirm that I did everything right xDD I hope I explained my thoughts now and you can show my errors imn my thoughts :) – KuSpa Mar 15 '18 at 12:33
  • @KuSpa the links you added explain that it is not possible to do this with aliases in sh-like shells (including zsh, the exception seems to be csh but don't use that) and you need to use functions instead. Why would you want to make your life complicated and try to force the function in your question into an alias instead of just using it as a function? – terdon Mar 15 '18 at 12:40
  • I want to recreate [this solution 1](https://stackoverflow.com/a/42466441/5862030) with `dmesg` i just wanna do it for fun and to set a users terminal outputs in color :), since they don't need to know, before they are surprised, i don't like the `f dmesg` idea, because it spoilers, that there is something special. ;) – KuSpa Mar 15 '18 at 12:47
  • The reason your function is doing nothing is because you set it and immediately `unset -f` it, so it isn't actually set (the reason why it works in the example you linked to and not here would be a valid question, if you want to post a new one asking about that). Just remove the `unset -f`. Or, even better, just define a function for this instead of an alias. Simply add `MyCommandName(){"$@" | lolcat;}` to your `.zshrc` and then you can run `MyCommandName dmesg`, just like you want. – terdon Mar 15 '18 at 12:50
  • I unset it in my function, so the function is called once, and then removes itself. – KuSpa Mar 15 '18 at 12:58
  • @terdon actually, the functions do work - the problem is that `$@` gets expanded to nothing when the alias is defined, so the function that's defined is actually `f () { "" | lolcat; ... }`. So the execution fails. The `unset -f` just clears the namespace after execution, that's OK. – muru Mar 15 '18 at 12:59
  • @muru the alias is in single quotes, why would it be expanded? `alias cc='f() { "$@" | lolcat ; uset -f f;};f'` and then `cc dmesg` works as expected. – terdon Mar 15 '18 at 13:00
  • I reopened since you are trying to understand something slightly different, but please [edit] and explain exactly how you want to run this. How did you "test with `dmesg`"? How do you want this to work? – terdon Mar 15 '18 at 13:04
  • @terdon ah, that's the latest version. My bad. OP: It seems you want to do something like `alias dmesg='f () { dmesg "$@" | lolcat; unset -f f; }; f'`. Is that right? – muru Mar 15 '18 at 13:04
  • yes, i did, but kind of generic, that I can use the function to alias ANY command and pipe this command into lolcat and the function knows by the passed parameter which command is used and does not need to be hardcoded – KuSpa Mar 15 '18 at 13:11

1 Answers1

2

If I understand right, you want to do something that takes a command name, say dmesg, and make it into something pipes its output to lolcat.

This is still best done using functions:

dmesg () { command "$0" "$@" | lolcat; }

That's as "generic" as it comes. The command command skips functions and calls builtins or executables: What is use of command: `command`?. $0, as you realised, is the name of the function, in this being the name of the command as well. So command "$0" runs the command with the same name as the function.

muru
  • 193,181
  • 53
  • 473
  • 722