Mengapa sudo mengabaikan alias?

22

Saya menjalankan Ubuntu 10,04 dan saya gunakan upstartuntuk manajemen daemon. Aplikasi perusahaan saya dijalankan sebagai daemon dan harus dijalankan sebagai root karena berbagai hak istimewa. Misalnya:

sudo start my-application-long-ID
sudo stop my-application-long-ID
etc

Saya ingin memperkenalkan sebuah aliasuntuk menyingkat perintah ini sebagai sesuatu seperti:

alias startapp='sudo start my-application-long-ID'

dan jalankan sebagai startappdan yang berfungsi tetapi saya lebih suka tidak memiliki sudo di alias.

alias startapp='start my-application-long-ID'

tidak ketika dijalankan menggunakan sudo startapp, kembali sudo: startapp: command not found.

Namun, ketika saya menambahkan alias:

alias sudo='sudo '

sudo startapp sekarang berfungsi tetapi saya masih penasaran mengapa sudo mengabaikan alias.

amfibi
sumber
Apakah Anda berlari source ~/.bashrc? Ini memperbarui file .bashrc dan membuat alias baru tersedia?
manu
@manu Ya, saya lakukan
amfibi
1
serverfault.com/questions/61321/how-to-pass-alias-through-sudo
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Jawaban:

35

Saya melihat informasi di bawah ini dari sini .

Saat menggunakan sudo, gunakan ekspansi alias (jika tidak sudo mengabaikan alias Anda)

alias sudo='sudo '

Alasan mengapa itu tidak berhasil dijelaskan di sini .

Bash hanya memeriksa kata pertama dari sebuah perintah untuk alias, kata-kata setelah itu tidak dicentang. Itu berarti dalam perintah seperti sudo ll, hanya kata pertama (sudo) diperiksa oleh bash untuk alias, ll diabaikan. Kita dapat memberi tahu bash untuk memeriksa kata berikutnya setelah alias (yaitu sudo) dengan menambahkan spasi di akhir nilai alias.

Ramesh
sumber
6

Alias ​​dan fungsi didefinisikan dalam sebuah shell. Sudo adalah program eksternal. Jadi sudo tidak melihat alias, fungsi atau shell builtin, hanya perintah eksternal.

Alias ​​dimaksudkan untuk menjadi nama perintah alternatif, jadi shell hanya memperluasnya di posisi perintah, bukan ketika mereka argumen untuk perintah. Zsh mendukung alias global, yang diperluas di mana saja di baris perintah, dan sebaiknya digunakan hemat karena ada risiko tidak sengaja mengembangkannya bahkan dalam konteks di mana alias tidak masuk akal.

Anda dapat memberitahu sudo untuk memohon shell: sudo sh -c '…shell command here…'. Namun, alias biasa Anda tidak akan tersedia di dalam perintah shell itu, karena biasanya disimpan dalam file seperti ~/.bashrcatau ~/.zshrcyang hanya dibaca oleh shell interaktif.

alias sudo='sudo ', seperti yang diusulkan oleh Ramesh , menyebabkan shell untuk memperluas alias setelahnya sudo.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
1
Apakah alias sudo='sudo 'bekerja untuk ZSH juga?
CMCDragonkai
2
@CMCDragonkai Ya
Gilles 'SO- stop being evil'
1

Solusi untuk pengguna zsh

Di bash dan zsh, mengakhiri alias dengan spasi akan menyebabkan shell alias-perluas kata berikutnya. Ini memungkinkan sesuatu seperti yang berikut ini diperluas aliasmyalias

alias 'sudo=sudo '
sudo myalias

Sayangnya ini berantakan ketika Anda memiliki lebih dari satu kata di alias Anda (seperti sudo -u someone. Namun Anda dapat menyalahgunakan fitur "global aliases" zsh untuk memperluas alias secara manual di mana saja dalam perintah.

alias -g '$= '

Ini menciptakan alias global yang disebut $(Anda dapat menggunakan kata apa pun yang Anda inginkan) yang berakhir dengan spasi. Ini menyebabkan zsh untuk memperluas kata berikutnya sebagai alias perintah biasa. Karena alias diperluas ke spasi putih, itu tidak akan diperlakukan sebagai argumen. Ini memungkinkan yang berikut berfungsi.

% alias myalias=echo
% sudo -u someone myalias foo
sudo: myalias: command not found
% sudo -u someone $ myalias foo
foo

Anda bahkan dapat menggunakan $beberapa kali pada satu baris perintah jika Anda memiliki penyatuan perintah yang rumit. Saya telah menemukan ini cukup berguna sehingga memiliki tempat permanen di zshrc saya, namun alias ini cukup sederhana untuk didefinisikan ketika Anda perlu menggunakannya.

Kevin Cox
sumber
0

Saya hanya memberikan jawaban alternatif di sini tanpa mendefinisikan ulang sudodengan alias.

Dalam kasus Anda itu adalah:

type -a startapp | grep -o -P "(?<=\`).*(?=')" | xargs sudo 

Semua dalam satu baris, tidak ada shell tambahan, tidak ada alias redefinisi. ;-)

dicintai.Yesus
sumber
Oh, tunggu dulu - saya mengerti - Anda menggunakan xargsuntuk menghilangkan tanda kutip, dan grep untuk menelanjangi yang terkemuka =. Agak pintar, tapi mungkin tidak perlu. eval "sudo $(alias aliasname | cut -d= -f2-)"kemungkinan lebih baik - xargstidak akan selalu menangani tanda kutip dengan benar, dan mungkin ada lebih dari satu =di sana.
mikeserv
@ mikeserv Maaf saya tidak mendapatkannya ;-) xargsjangan mencabut tanda kutip. Grep yang mengambil perintah yang diselesaikan dari antara tanda kutip. Anda tahu type -a alias_namemengembalikan sesuatu seperti alias_name is aliased to command_within_quotes. Ngomong-ngomong, saya sudah mencoba perintah Anda dan tidak bekerja di ubuntu saya :-(. Apakah ini kembalinya type -aperbedaan antara versi linux? (Saya ragu).
loved.by.Jesus
Saya tahu apa yang typeterjadi bash. Anda mengerti, bahwa tanda kutip digandakan, bukan? Sudahkah Anda mencobanya dengan alias yang berisi tanda kutip tunggal? Lagi pula, Anda benar tentang hal saya tidak berfungsi - Anda perlu eval "sudo sh -c "$(...atau eval "'sudo $(alias alias_name| cut -d\' -f2-)". Masalahnya adalah aliases pada dasarnya sudah diatur sebelumnya eval- aliasutilitas ditentukan untuk menampilkan kontennya sehingga dapat dengan aman di-instal kembali ke shell. Saya kira Anda xargsdiimplementasikan kemudian untuk meratakan ruang putih? Berhati-hatilah dengan itu, ok?
mikeserv