# How to pass alias through sudo

I have an alias that passes in some parameters to a tool that I use often. Sometimes I run as myself, sometimes under sudo. Unfortunately, of course, sudo doesn't recognise the alias.

Does anyone have a hint on how to pass the alias through?

In this case, I have a bunch of options for perl when I'm debugging:

alias pd='perl -Ilib -I/home/myuser/lib -d'


Sometimes, I have to debug my tools as root, so, instead of running:

pd ./mytool --some params


I need to run it under sudo. I've tried many ways:

sudo eval $(alias pd)\; pd ./mytool --some params sudo$(alias pd)\; pd ./mytool --some params
sudo bash -c "$(alias pd)\; pd ./mytool --some params" sudo bash -c "$(alias pd); pd ./mytool --some params"
sudo bash -c eval\ "$(alias pd)\; pd ./mytool --some params" sudo bash -c eval\ "'$(alias pd)\; pd ./mytool --some params'"


I was hoping for a nice, concise way to ensure that my current pd alias was fully used (in case I need to tweak it later), though some of my attempts weren't concise at all. My last resort is to put it into a shell script and put that somewhere that sudo will be able to find. But aliases are soooo handy sometimes, so it is a last resort.

-

Can you add the alias to root's .bashrc or just execute .bashrc through sudo before your command?

sudo (. ~yourlogin/.bashrc; pd ./mytool --some params)

-
Um, this didn't even almost work, either. It's actually fairly close to some of the things I tried above, but is further away from actual shell/sudo syntax. – Tanktalus Sep 1 '09 at 21:34

Wouldn't it be easier to simply hack out a script that includes your options, then place it somewhere in one of the folders that is the path for regular account and root? It really wouldn't take much of a script.

#!/bin/bash
exec perl -Ilib -I/home/myuser/lib -d $*  - It actually has to be "$@" instead of $*, and that's part of the reason I generally try to avoid it. ;-) It works, it just wastes a bunch of disk space relative to what it contains. – Tanktalus Sep 1 '09 at 21:22 This is rough, but it works here: houdini@clanspum:~/ > alias fb fb='echo foo bar' houdini@clanspum:~/ > alias fb | awk -F\' '{print$2}'
echo foo bar
houdini@clanspum:~/ > sudo sh -c "$(alias fb | awk -F\' '{print$2}')"
foo bar
houdini@clanspum:~/ > sudo sh -c "$(alias fb | awk -F\' '{print$2}') a b c"
foo bar a b c
houdini@clanspum:~/ > fb
foo bar
houdini@clanspum:~/ > fb a b c
foo bar a b c

-
I pasted an incomplete solution here, then edited to fix. The current one is right. A free upvote to the first person to comment explaining what's going on here :) – Bill Weiss Sep 1 '09 at 22:02
I was hoping for a simpler way than awk, but hope != reality sometimes ;-) Apparently, "cut -f2 -d\'" would work just as well as awk, and be that tiny bit shorter. – Tanktalus Sep 1 '09 at 22:05
Yeah, cut would work, I always forget about it. – Bill Weiss Sep 1 '09 at 22:07

I'm not real clear on what you're trying to do. I can see two ways:

## The Right Way

alias pd='sudo perl -Ilib -I/home/myuser/lib -d'

Then executing pd ./mytool will execute your debugging command as root but still preserve the benefits of sudo (audit trail, not operating out of a root shell).

Example:

insyte$alias sid='sudo id' insyte$ sid
uid=0(root) gid=0(root) groups=0(root)


## The Easy Way

Add the aliases to root's .bashrc and use sudo -i whenever you sudo to root.

root# echo 'alias fb="echo foo bar"' >> /root/.bashrc
root# exit
exit
insyte$sudo -i root# fb foo bar  - facepalm ++ - that was too obvious, thanks. – Tanktalus Sep 1 '09 at 22:54 You want something like this: (alias; echo "exec < /dev/tty") | sudo bash -i  - I might be wrong, but ISTR that bash -i (i = interactive) is v4.0 only. So on an older server that still got bash v3 running, this would most likely fail. But prove me wrong, anyone, go ahead ;) – syntaxerror Jan 29 at 16:35 @syntaxerror - You remember wrong. -i is Bourne shell, see: pubs.opengroup.org/onlinepubs/009695399/utilities/sh.html – geocar Jan 29 at 17:57 Wow, didn't expect to get a reply so soon for a 6+-year-old post...Why yes, I might have confused it with #!/bin/bash -i after the shebang, which is apparently not the same (?). To cut a long story short, using history in a bash script (and not on the "live" command line) will require the -i option, which I was unable to get working on a server with "only" bash v3 installed. And that's a fact. – syntaxerror Jan 29 at 18:18 I wish I could mark two answers as "correct". Combining the Right Way from Insyte's, um, insightful post, with the awk (or cut) solution from Bill Weiss, I've come up with this: alias spd="sudo$(alias pd | cut -d\' -f2)"


Now I'll just go and put this into a shell function in my .bashrc or something, and then create "s" versions of all my aliases that I desire to run as root.

Update: slight modification of Dennis Williamson's simplistic function to make it a bit easier to use:

 salias()
{
local a c
a=$(echo "$1" | cut -f1 -d=)
c=$(echo "$1" | cut -f2- -d=)
alias $a="$c"
alias s$a="sudo$c"
}


This means I just have to put "s" in front of the entire command. Instead of:

alias pd='perl -Ilib -I/home/myuser/lib -d'


I just add the s in the front.

salias pd='perl -Ilib -I/home/myuser/lib -d'


And I'm done. Sure, the computer does a bit more work, but that's what a computer is for. :-)

Thanks!

-
You can (or should be able to) mark things as accepted, which is kind of like marking them correct :) – Bill Weiss Sep 2 '09 at 15:09
Right - I want to mark two answers as correct :-P – Tanktalus Sep 2 '09 at 17:51
Why not Slizzered's answer? alias sudo="sudo " works perfect. – trusktr Nov 5 '12 at 22:08

Just have two aliases and use a variable

I don't see the reason for using awk or cut unless it's to only have the core alias defined once in order to make it easier to modify. If that's the case, then this works:

# ... in .bashrc ...
pd='perl -Ilib -I/home/myuser/lib -d'
alias pd="$pd" alias spd="sudo$pd"


Here's a simplistic function to make alias pairs such as the one above:

mkap () {
alias $1=$2
alias s$1="sudo$2"
}


To use:

mkap pd 'perl -Ilib -I/home/myuser/lib -d'
mkap ct 'cat'


Now you have pd and spd plus ct and sct.

$ct /etc/shadow cat: /etc/shadow: Permission denied$ sct /etc/shadow
root:[censored]...
$alias alias ct='cat' alias pd='perl -Ilib -I/home/myuser/lib -d' alias sct='sudo cat' alias spd='sudo perl -Ilib -I/home/myuser/lib -d'  - Add a "sudo " prefix to selected aliases AND commands from within your ~/.bashrc like so: #a regular alias alias pd='perl -Ilib -I/home/myuser/lib -d' #sudofy (command id, alias pd - add others to this list) for cmd in id pd; do alias "s$cmd"="sudo \$cmd";
done;

-
That doesn't work - that's where I started from. Did you try it? – Tanktalus Oct 8 '09 at 5:23
Nice concept. I think alias sudo="sudo " is easier though. – trusktr Nov 5 '12 at 22:10

A very elegant solution can be found in the Archlinux-Wiki:

alias sudo='sudo '
# whitespace ---^


works to pass all aliases to sudo.

-
This is a great trick! For the curious, the explanation from the alias section in the bash manpage: A trailing space in value causes the next word to be checked for alias substitution when the alias is expanded. – Russell Davis Nov 23 '11 at 19:36
This should really be the accepted answer. – Adrian Frühwirth Oct 11 '13 at 7:39
It is a shame that this does not work for functions. – Ciro Santilli 六四事件 法轮功 包卓轩 Aug 9 '15 at 19:46
Note: Supposing you DO need to pass an option to sudo again, while wanting to keep that sudo-passthrough trick at the same time. Even this can be done: to use options again, use \sudo. The backslash will override the alias. (Many don't seem to know about that). This way, you can (danger!) even remove files without any warning, overriding the alias rm='rm -i' commonly specified in .bash-aliases, simply by typing \rm file-to-delete. – syntaxerror Jan 29 at 16:16
alias sudo='sudo '

-

As posted a few times, do in '.bashrc':

alias sudo='sudo '

The reason why is explained in 'man bash' and 'help alias':

alias: alias [-p] [name[=value] ... ] Define or display aliases.

Without arguments, alias' prints the list of aliases in the reusable
form alias NAME=VALUE' on standard output.

Otherwise, an alias is defined for each NAME whose VALUE is given.
**A trailing space in VALUE causes the next word to be checked for
alias substitution when the alias is expanded.**

-

I don't know if it's the wisest thing to do on a production box but locally I use

alias sudo="sudo -E"


The -E (preserve environment) option will override the env_reset option in sudoers(5)). It is only available when either the matching command has the SETENV tag or the setenv option is set in sudoers(5).

-