Cara melewati alias melalui sudo

32

Saya memiliki alias yang meneruskan beberapa parameter ke alat yang sering saya gunakan. Kadang saya berlari seperti diri saya sendiri, kadang di bawah sudo. Sayangnya, tentu saja, sudo tidak mengenali alias.

Adakah yang punya petunjuk tentang cara melewati alias?

Dalam hal ini, saya memiliki banyak opsi untuk perl ketika saya sedang melakukan debug:

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

Terkadang, saya harus men-debug alat saya sebagai root, jadi, bukannya menjalankan:

pd ./mytool --some params

Saya perlu menjalankannya di bawah sudo. Saya sudah mencoba banyak cara:

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'"

Saya berharap cara yang bagus dan ringkas untuk memastikan bahwa alias pd saya saat ini sepenuhnya digunakan (kalau-kalau saya perlu mengubahnya nanti), meskipun beberapa upaya saya tidak ringkas sama sekali. Pilihan terakhir saya adalah memasukkannya ke dalam skrip shell dan meletakkannya di suatu tempat yang bisa ditemukan oleh sudo. Tapi terkadang alias sangat berguna, jadi ini pilihan terakhir.

Tanktalus
sumber

Jawaban:

50

Solusi yang sangat elegan dapat ditemukan di Archlinux-Wiki:

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

berfungsi untuk meneruskan semua alias ke sudo.

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

Slizzered
sumber
16
Ini trik yang bagus! Bagi yang penasaran, penjelasan dari bagian alias di halaman bash:A trailing space in value causes the next word to be checked for alias substitution when the alias is expanded.
Russell Davis
1
Ini benar-benar jawaban yang diterima.
Adrian Frühwirth
Sayang sekali ini tidak berfungsi untuk fungsi.
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
2
Catatan: Misalkan Anda DO perlu lulus pilihan untuk sudolagi, sementara ingin menjaga sudotrik -passthrough pada saat yang sama. Bahkan ini bisa dilakukan: untuk menggunakan opsi lagi, gunakan \sudo. Garis miring terbalik akan menimpa alias. (Banyak yang sepertinya tidak tahu tentang itu). Dengan cara ini, Anda dapat ( bahaya! ) Bahkan menghapus file tanpa peringatan apa pun , mengesampingkan yang alias rm='rm -i'umum ditentukan .bash-aliases, hanya dengan mengetik \rm file-to-delete.
syntaxerror
11

Saya tidak begitu jelas tentang apa yang Anda coba lakukan. Saya bisa melihat dua cara:

Jalan yang benar

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

Kemudian mengeksekusi pd ./mytoolakan menjalankan perintah debug Anda sebagai root tetapi masih mempertahankan manfaat sudo (jejak audit, tidak beroperasi dari shell root).

Contoh:

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

Cara Mudah

Tambahkan alias ke root .bashrcdan gunakan sudo -ikapan saja Anda sudo untuk root.

root # echo 'alias fb = "echo foo bar"' >> /root/.bashrc
root # exit
keluar
insyte $ sudo -i
root # fb
bar foo
Insyte
sumber
4

Hanya punya dua alias dan gunakan variabel

Saya tidak melihat alasan untuk menggunakan awkatau cutkecuali itu hanya untuk memiliki alias inti yang didefinisikan sekali untuk membuatnya lebih mudah untuk dimodifikasi. Jika itu masalahnya, maka ini berfungsi:

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

Berikut adalah fungsi sederhana untuk membuat pasangan alias seperti yang di atas:

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

Menggunakan:

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

Sekarang Anda memiliki pddan spdplus ctdan 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'
Dijeda sampai pemberitahuan lebih lanjut.
sumber
4

Saya berharap saya dapat menandai dua jawaban sebagai "benar". Menggabungkan Jalan yang Benar dari posting Insyte , um, penuh wawasan, dengan solusi awk (atau cut) dari Bill Weiss , saya datang dengan ini:

alias spd="sudo $(alias pd | cut -d\' -f2)"

Sekarang saya hanya akan pergi dan memasukkan ini ke dalam fungsi shell di .bashrc saya atau sesuatu, dan kemudian membuat versi "s" dari semua alias saya yang ingin saya jalankan sebagai root.

Pembaruan : sedikit modifikasi dari fungsi sederhana Dennis Williamson untuk membuatnya sedikit lebih mudah digunakan:

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

Ini berarti saya harus meletakkan "s" di depan seluruh perintah. Dari pada:

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

Saya hanya menambahkan s di bagian depan.

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

Dan saya sudah selesai. Tentu, komputer bekerja sedikit lebih banyak, tetapi untuk itulah komputer itu digunakan. :-)

Terima kasih!

Tanktalus
sumber
Anda dapat (atau seharusnya dapat) menandai hal-hal yang diterima, yang semacam suka menandainya dengan benar :)
Bill Weiss
Benar - Saya ingin menandai dua jawaban sebagai benar :-P
Tanktalus
3
Kenapa bukan jawaban Slizzered? alias sudo="sudo "bekerja dengan sempurna.
trusktr
3

Bukankah lebih mudah untuk meretas skrip yang menyertakan opsi Anda, lalu letakkan di suatu tempat di salah satu folder yang merupakan jalur untuk akun dan root biasa? Ini benar-benar tidak akan membutuhkan banyak naskah.

#!/bin/bash
exec perl -Ilib -I/home/myuser/lib -d $*
Sakit kepala
sumber
Ini sebenarnya harus "$ @", bukan $ *, dan itulah bagian dari alasan saya biasanya mencoba menghindarinya. ;-) Berhasil, hanya membuang banyak ruang disk relatif terhadap apa yang dikandungnya.
Tanktalus
3

Ini kasar, tetapi berfungsi di sini:

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
sumber
Saya menempelkan solusi yang tidak lengkap di sini, lalu diedit untuk memperbaikinya. Yang sekarang benar. Suara positif gratis untuk orang pertama yang mengomentari menjelaskan apa yang terjadi di sini :)
Bill Weiss
Saya berharap untuk cara yang lebih sederhana daripada awk, tapi harapan! = Kenyataan kadang-kadang ;-) Rupanya, "cut -f2 -d \ '" akan bekerja sama baiknya dengan awk, dan menjadi sedikit lebih pendek.
Tanktalus
Ya, potong akan berhasil, saya selalu melupakannya.
Bill Weiss
3

Tambahkan awalan "sudo" ke alias yang dipilih DAN perintah dari dalam ~/.bashrcseperti Anda :

#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;

sumber
Itu tidak berhasil - di situlah saya mulai. Apakah kamu sudah mencobanya?
Tanktalus
Konsep yang bagus Saya pikir alias sudo="sudo "lebih mudah.
trusktr
3

Seperti yang diposting beberapa kali, lakukan di '.bashrc':

alias sudo = 'sudo'

Alasan mengapa dijelaskan dalam 'man bash' dan 'help alias':

alias: alias [-p] [nama [= nilai] ...] Tentukan atau tampilkan alias.

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

Anda menginginkan sesuatu seperti ini:

(alias; echo "exec < /dev/tty") | sudo bash  -i
geocar
sumber
Saya mungkin salah, tetapi ISTR itu bash -i(i = interaktif) hanya v4.0. Jadi pada server lama yang masih bashmenjalankan v3, ini kemungkinan besar akan gagal. Tapi buktikan saya salah, siapapun, silakan;)
syntaxerror
@syntaxerror - Anda ingat salah. -iadalah Bourne shell, lihat: pubs.opengroup.org/onlinepubs/009695399/utilities/sh.html
geocar
Wow, tidak berharap mendapat balasan secepatnya untuk pos 6 tahun-lama ... Kenapa ya, saya mungkin bingung dengan #!/bin/bash -isetelah shebang, yang ternyata tidak sama (?). Untuk memotong cerita panjang pendek, menggunakan historydalam bashnaskah (dan bukan pada "hidup" baris perintah) akan membutuhkan -ipilihan, yang saya tidak mampu untuk mendapatkan bekerja pada server dengan "hanya" bashv3 diinstal. Dan itu fakta.
syntaxerror
1

Saya tidak tahu apakah itu hal paling bijak untuk dilakukan di kotak produksi tetapi secara lokal saya gunakan

alias sudo="sudo -E"

Opsi -E ( lingkungan preservasi ) akan menggantikan opsi env_reset di sudoers (5)). Ini hanya tersedia ketika perintah pencocokan memiliki tag SETENV atau opsi setenv diatur dalam sudoers (5).

Eddie B
sumber
-1

Bisakah Anda menambahkan alias ke root .bashrc atau hanya menjalankan .bashrc melalui sudo sebelum perintah Anda?

sudo (. ~yourlogin/.bashrc; pd ./mytool --some params)
Robert Swisher
sumber
1
Um, ini bahkan hampir tidak berhasil. Ini sebenarnya cukup dekat dengan beberapa hal yang saya coba di atas, tetapi lebih jauh dari sintaks shell / sudo yang sebenarnya.
Tanktalus