32

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.

12 Answers 12

55

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

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

works to pass all aliases to sudo.

Source: http://wiki.archlinux.org/index.php/Sudo#Passing_aliases

4
  • 18
    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. Nov 23, 2011 at 19:36
  • 1
    This should really be the accepted answer. Oct 11, 2013 at 7:39
  • It is a shame that this does not work for functions. Aug 9, 2015 at 19:46
  • 3
    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. Jan 29, 2016 at 16:16
12

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
1
  • It's not clear to me what all the debate is about. Insyte's "Right Way" seems easiest, and in a departure from the norm, also seems most intuitive.
    – Seamus
    Dec 8, 2020 at 1:19
5

from http://www.shellperson.net/using-sudo-with-an-alias/

alias sudo='sudo '
4

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
[sudo] password for dennis:
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'
4

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!

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

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 $*
1
  • 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, 2009 at 21:22
3

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
3
  • 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, 2009 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, 2009 at 22:05
  • Yeah, cut would work, I always forget about it.
    – Bill Weiss
    Sep 1, 2009 at 22:07
3

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;
2
  • That doesn't work - that's where I started from. Did you try it?
    – Tanktalus
    Oct 8, 2009 at 5:23
  • Nice concept. I think alias sudo="sudo " is easier though.
    – trusktr
    Nov 5, 2012 at 22:10
3

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.**
1

You want something like this:

(alias; echo "exec < /dev/tty") | sudo bash  -i
3
  • 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 ;) Jan 29, 2016 at 16:35
  • @syntaxerror - You remember wrong. -i is Bourne shell, see: pubs.opengroup.org/onlinepubs/009695399/utilities/sh.html
    – geocar
    Jan 29, 2016 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. Jan 29, 2016 at 18:18
1

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).

-1

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)
1
  • 1
    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, 2009 at 21:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .