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.

Tanktalus
  • 461

12 Answers12

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

Slizzered
  • 814
  • 6
  • 17
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
Insyte
  • 9,554
5

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

alias sudo='sudo '
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!

Tanktalus
  • 461
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'
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.**
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 $*
Zoredache
  • 133,737
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
Bill Weiss
  • 11,266
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;
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

You want something like this:

(alias; echo "exec < /dev/tty") | sudo bash  -i
geocar
  • 2,317
-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)