Saya memiliki fungsi di ~/.zshrc
:
findPort() {
lsof -t -i :$1
}
Doa yang biasa adalah findPort 3306
.
Saya ingin menjalankannya dengan hak istimewa yang ditinggikan. Tapi saya mendapatkan "perintah tidak ditemukan".
➜ git 🍔 sudo findPort 3306
sudo: findPort: command not found
Saya kira alasannya adalah bahwa pengguna root berjalan sebagai shell non-interaktif (dengan demikian tidak merujuk ke .zshrc), atau merujuk ke yang berbeda .zshrc
.
Saya telah melihat pertanyaan serupa tentang alias
, tetapi tidak ada pertanyaan tentang fungsi yang ditentukan pengguna. Jawaban untuk masalah ini terkait alias
dengan menambahkan alias ke ~/.zshrc
:
alias sudo='nocorrect sudo '
Atau mungkin:
alias sudo='sudo '
Saya sudah mencoba kedua solusi ini, dan masalahnya masih ada (ya saya sudah meluncurkan shell).
Saya juga mencoba menjalankan sudo chsh
untuk memastikan bahwa shell root saya berjalan di bawah zsh
. Tak satu pun dari solusi ini menghilangkan masalah "perintah tidak ditemukan".
Apakah ada cara untuk menjalankan fungsi yang ditentukan pengguna saya di bawah sudo?
Jawaban:
sudo
berjalan perintah langsung, tidak melalui shell, dan bahkan jika itu berlari shell untuk menjalankan perintah itu, itu akan menjadi shell doa baru, dan bukan salah satu yang berbunyi Anda~/.zshrc
(bahkan jika itu mulai shell interaktif, mungkin akan membacaroot
's~/.zshrc
, bukan milik Anda kecuali Anda telah mengkonfigurasisudo
untuk tidak mereset$HOME
variabel).Di sini, Anda perlu memberi tahu
sudo
untuk memulaizsh
shell baru , dan mengatakan ituzsh
untuk membaca Anda~/.zshrc
sebelum menjalankan fungsi itu:Atau:
Atau untuk berbagi fungsi zsh Anda saat ini dengan yang baru
zsh
dipanggil olehsudo
:Meskipun Anda mungkin mendapatkan daftar argumen terlalu lama jika Anda memiliki banyak fungsi yang didefinisikan (seperti saat menggunakan sistem penyelesaian). Jadi, Anda mungkin ingin membatasinya ke
findPort
fungsi (dan setiap fungsi lain yang diandalkannya jika ada):Anda juga bisa:
Untuk menyematkan kode
findPort
fungsi dalam fungsi anonim yang Anda gunakan argumen 3306. Atau bahkan:(script inline diteruskan ke
-c
adalah tubuh fungsi).Anda dapat menggunakan fungsi pembantu seperti:
Jangan gunakan:
Sebagai argumen
sdo
akan menjalani tingkat penguraian shell. Membandingkan:sumber
sudo
. Saya dapat mengadaptasi solusi fungsi anonim Anda untuk melakukan hal itu. Saya telah menambahkan fungsi berikut ke saya~/.zshrc
, yang merupakan fungsi untuk menjalankan fungsi lain dengan hak istimewa yang ditingkatkan:sdo() { sudo zsh -c "(){$functions[$1]} ${@:2}" }
Solusi yang sangat sederhana bagi saya adalah menggunakan shell interaktif menggunakan
sudo -s
, yang tampaknya berfungsi pada versi berkas macOS saya dari zsh (5.2). Ini memberi saya fungsi dari~/.zshrc
.Dari manual sudo, yang sebenarnya tidak mengisyaratkan perilaku ini:
Saya tidak yakin apa kasus penggunaan Anda, tetapi saya curiga Anda sedang mencari solusi interaktif.
sumber
myFunc
, dengan mengetiksudo myFunc
- dengan cara yang sama saya akan meningkatkan proses apa pun (sepertisudo rm -rf .
). Solusi ini meningkatkan seluruh fungsi prompt dan semua fungsi saya di masa depan, serta mengubah pengguna saya untuk semua fungsi di masa depan - yang sedikit berlebihan.sudo -s
perintah akan meluncurkan contoh lain dari shell Anda sebagai superuser. Jika Anda menjalankan perintah itu secara interaktif, shell baru Anda akan interaktif. Tetapi perintah itusudo -s findPort 3306
akan menjalankan perintahfindPort 3306
di shell Anda sebagai superuser kemudian keluar dengan kode status dari perintah itu.Saya dapat menghasilkan steno yang dapat digunakan kembali untuk salah satu solusi yang dijelaskan dalam jawaban Stéphane Chazelas . [Sunting: Stéphane telah mengulangi pada pintasan asli yang saya usulkan; kode yang dijelaskan di sini adalah versi yang lebih baru, dari pembuatannya]
Masukkan ini ke Anda
~/.zshrc
:Sekarang Anda dapat menggunakan
sdo
sebagai "hanyasudo
untuk fungsi yang ditentukan pengguna".Untuk mengonfirmasi bahwa
sdo
berfungsi: Anda dapat mencobanya pada fungsi yang ditentukan pengguna yang mencetak nama pengguna Anda.sumber
Ini sepertinya bekerja untuk saya:
sumber