Saya telah menyesuaikan .bashrc
dengan sejumlah alias, khusus ll
danexport LS_OPTIONS='--color=auto'
Sayangnya ini tidak berfungsi ketika digunakan dengan sudo
, jadi saya juga dimodifikasi /root/.bashrc
, tetapi ini tampaknya tidak membuat perbedaan.
sudo env
menunjukkan HOME=/root
danSHELL=/bin/bash
Bagaimana saya bisa mendapatkan sudo
perintah untuk menggunakan pengaturan /root/.bashrc
?
Saya mengerti bahwa ini hanya terjadi ketika bash
dijalankan secara interaktif, jadi saya terbuka untuk saran lain tentang cara menyesuaikan.
/root/.bashrc
tetapi yang benar-benar dicari Q adalah alias dari file ini - ini tidak mungkin untuk ini - unix.stackexchange.com/questions/1496/… .-r
pilihan untukcrontab
:crontab () { [[ $@ =~ -[iel]*r ]] && echo '"r" not allowed' || command crontab "$@" ;}
. Ini berfungsi ketika masuk sebagai salah satu pengguna, namun ketika saya menjalankannyasudo crontab -r
masih dijalankan.Jawaban:
sudo
menjalankan executable, bukan perintah shell. Jadi tidak tahu tentang alias. Jika Anda menjalankansudo ls
, itu sepertisudo /bin/ls
, itu tidak menggunakanls
alias apa pun yang mungkin Anda miliki.Anda dapat menyebabkan
sudo ls
untuk memperluas alias dengan memasukkan yang berikut ini di.bashrc
:Perhatikan spasi tambahan - yang memberi tahu shell untuk melanjutkan alias ekspansi dengan kata yang muncul setelahnya
sudo
. Berhati-hatilah bahwa memperluas alias setelah sudo mungkin tidak selalu merupakan ide yang baik, tergantung pada jenis alias apa yang Anda miliki.Lebih jauh lagi, sudo menghapus sebagian besar variabel dari lingkungan. Ini tidak akan memengaruhi alias seperti
alias ls='ls $LS_OPTIONS'
, karena itu adalah variabel shell yang digunakan oleh shell saat sedang memperluas perintah (dan mengekspornya dari.bashrc
tidak berguna). Tetapi itu akan mempengaruhi variabel yang digunakan oleh perintah, sepertiLS_COLORS
. Anda dapat mengonfigurasi sudo untuk menjaga variabel lingkungan tertentu dengan mengedit konfigurasinya: jalankanvisudo
dan tambahkan barisDengan pengaturan ini,
sudo ll
akan memberikan warna yang biasa Anda gunakan.Atau, Anda dapat menjalankan shell root dengan
sudo -s
. Shell ini akan memuat file konfigurasinya (~/.bashrc
untuk bash). Bergantung pada bagaimana sudo dikonfigurasi, ini dapat tetapHOME
diatur ke direktori home Anda, atau mengubahnya menjadi/root
. Anda bisa memaksa direktori home diatur ke root dengansudo -Hs
; sebaliknya, untuk menjaga direktori home asli, jalankansudo env HOME="$HOME" bash
.sumber
Terima kasih kepada mereka yang menjawab, yang mendorong saya untuk membaca
man sudo
lebih cermat.sudo -s
Jika tidak ada perintah yang ditentukan, shell interaktif dijalankan.Shell interaktif ini menggunakan
/root/.bashrc
dan dengan demikian termasuk penyesuaian saya.Itu memang mengharuskan perintah dimasukkan secara terpisah, tetapi ini OK.
sumber
Latar Belakang
Saya selalu merasa pertanyaan ini adalah masalah XY . Judul menyiratkan bahwa mereka menginginkan sesuatu
/root/.bashrc
tetapi sebenarnya pertanyaannya adalah alias dari file ini - ini secara luas diyakini tidak mungkin dilakukan per ini - Mengapa skrip Bash saya tidak mengenali alias? .Ini pada dasarnya dengan desain bahwa alias Anda tidak akan dijemput di
sudo
dan di tempat lain karena mereka tidak portabel, dan ini adalah pendapat saya tentang mereka juga.Apa pun yang ada di lingkungan pengguna tidak boleh diasumsikan oleh skrip dan perangkat lunak apa pun yang dapat berjalan pada kotak yang diberikan. Tapi saya menyadari bahwa ada skenario di mana mungkin ada beberapa alias dalam akun pengguna tertentu
$HOME/.bashrc
yang mungkin ingin dimanfaatkan orang lain dalam skenario interaktif.Untuk itu Anda bisa memberi tahu penerjemah Bash untuk memperluas alias apa pun yang ditemukannya selama proses login di luar perilaku shell normal yang Anda alami ketika menggunakan
sudo
.Contoh
Mendirikan
Untuk mengaturnya, saya telah menambahkan alias, variabel lingkungan, dan fungsi berikut ke pengguna
/root/.bashrc
dan/root/.bash_profile
file root saya .Tanpa melakukan apa pun, kedua pekerjaan ini (tidak ada kejutan):
Kita melihat bahwa
alias
perintah tidak menunjukkan alias ketika dijalankan disudo
:Perilaku ini adalah petunjuk Anda bahwa Anda seharusnya tidak berharap alias dapat diakses. Tapi kami melanjutkan ...
Langkah # 1 - alias terlihat
Jika kami menjalankan,
bash -ci
kami dapat mendorong Bash untuk setidaknya membaca$HOME/.bashrc
:Keren, jadi mungkin kita bisa menjalankannya?
Langkah 2 -
shopt -s expand_aliases
Nggak. Sekali lagi ini adalah dengan desain, kami melakukan sesuatu yang seharusnya tidak kami lakukan, jadi ada sejumlah "pengaman" yang harus kami nonaktifkan. "keamanan" lainnya adalah Bash.
Di sini kita dapat melihat pesan kami dari
/root/.bashrc
, kami telah berhasil menjalankan alias pengguna rootbrc_smurf
.Langkah # 3 - bagaimana dengan env vars?
Jika Anda menggunakan metode yang ditunjukkan di atas ini sekarang harus bekerja juga.
Langkah # 4 - bagaimana dengan fungsi?
Ini juga berfungsi seperti yang diharapkan:
TLDR;
Anda dapat melakukan ini untuk mendapatkan akses ke variabel lingkungan + alias dari
/root/.bashrc
:Awasi
Metode ini memungkinkan konten
/root/.bashrc
, tidak mengambil konten/root/.bash_profile
.Referensi
sumber
.bashrc
dengan sudo; khusus menghapus-r
opsi daricrontab
?sudo bash -ci 'alias; shopt -s expand_aliases; echo $brc_smurf_env'
bukannya yang sederhanasudo echo $brc_smurf_env
?alias
, itu hanya untuk menunjukkan kepada mereka, yang perlu Anda lakukansudo bash -ci 'shopt -s expand_aliases; <cmds>'
Ada banyak pengaturan di file / etc / sudoers khusus atau pengaturan lingkungan ketika perintah sudo dijalankan (mis. Memastikan PATH hanya memiliki lokasi tepercaya) tetapi tergantung pada apa yang Anda harapkan untuk keluar dari ini Anda mungkin tidak dapat melakukan apa yang Anda inginkan jika itu melibatkan menjalankan perintah aktual dalam shell untuk mengatur lingkungan. Sudoing secara khusus tidak memberi Anda shell login root sehingga tidak akan mengatur profil reguler untuk Anda.
sumber
Katakanlah kita mengedit /root/.bashrc menjadi:
Mari keluar dan masuk kembali untuk membuat bash membaca file:
Seperti yang Anda lihat, file telah dibaca, PATH telah diubah dan alias telah ditetapkan. Semua fungsional sesuai permintaan Anda.
Namun, sudo masih tidak berfungsi seperti yang Anda harapkan.
PATH belum berubah. Mungkin ada cara untuk mengubah jalur di sudoers, tetapi saya sangat menyarankan Anda untuk menghindari melakukan itu. Lagi pula, alias, fungsi, dan beberapa perubahan lainnya masih tidak akan diterapkan dengan mengubah hanya PATH. File harus bersumber. Melakukan itu untuk setiap skrip atau perintah akan meminta komputer untuk melakukan lebih banyak pekerjaan tanpa manfaat nyata. Script tidak menggunakan alias (tidak ada penggunaan praktis untuk mereka di dalam skrip).
Jadi, cukup login,
.bashrc
file akan dimuat secara otomatis dan mulai bekerja.Anda dapat memulai bash karena ini:
Tetapi seperti yang Anda lihat di atas, pwd (direktori kerja) tidak berubah, dan, jika Anda memeriksa sedikit lebih, beberapa pengaturan lain tidak berubah juga. Itulah sebabnya perintah yang benar adalah menggunakan:
Jika perintah itu terlalu panjang untuk diketik, buat alias atau fungsi di pengguna (bukan root) tempat perintah itu akan digunakan, sesuatu seperti:
sumber
TL; DR: Anda dapat menggunakan
sudo -i
untuk menjalankan fungsi yang ditentukan/root/.bashrc
(tetapi bukan alias) dan juga memiliki akses ke variabel yang diekspor dari file itu:Meskipun demikian, alias tidak berfungsi di sana, tetapi Anda dapat dengan mudah mengonversinya ke fungsi jika Anda ingin membuatnya tersedia
sudo -i
.Baca terus untuk analisis penuh dan detail lebih lanjut.
Ada beberapa masalah di sini, beberapa dalam cara kerja sudo dan beberapa dalam cara bash itu bekerja ...
Secara default,
sudo
hanya akan mencari perintah dan akan memotong shell, jadi hanya menjalankansudo ll
hanya akan bekerja jika ada yang dapatll
dieksekusi di salah satu direktori di$PATH
. Jadi, untuk menggunakan alias (atau fungsi), Anda perlu memastikan shell dipanggil sebagai bagian dari proses.Salah satu caranya adalah dengan menjalankan sesuatu seperti
sudo sh
atausudo bash
, meskipun modernsudo
(saya menguji ini pada sudo 1.8.19p1) memiliki opsi-s
dan-i
untuk tujuan itu.Jadi satu percobaan akan menjadi sesuatu seperti
sudo -s ll
(yang setara dengansudo bash -c 'll'
, dengan asumsi Anda$SHELL
adalah Bash, yang tampaknya menjadi kasus berdasarkan yangrcfile
Anda sebutkan.) Tapi itu tidak berhasil, karena ia memulai shell dalam non-interaktif, mode non-login, yang tidak membaca file startupnya. Ini pada dasarnya sama seperti jika Anda menulis skrip shell dan menggunakannya#!/bin/bash
untuk menjalankannya. Alias (dan fungsi) yang Anda miliki di Anda~/.bashrc
tidak akan dapat diakses dari skrip itu ...Jadi selanjutnya adalah
-i
opsi, yang menciptakan shell login. Itu lebih menjanjikan, karena akan membaca file startup Anda! Namun,sudo -i ll
(setara dengansudo bash -l -c 'll'
) masih tidak akan berfungsi. Jadi bagaimana mungkin, mengingat memang membaca definisill
alias?Nah, penjelasan selanjutnya di sini adalah bahwa, secara default, bash tidak akan memperluas alias, kecuali ketika shell bersifat interaktif ... Shell ini dimulai dengan
sudo -i
(ataubash -l
) shell login , tetapi masih belum interaktif.Jadi langkah selanjutnya adalah mendapatkan shell interaktif , yang kemudian berfungsi :
(Memiliki kedua login dan interaktif juga baik, tentu saja,
bash -l -i -c ...
akan berfungsi.)Alternatif lain adalah tetap menggunakan shell login (non-interaktif) tetapi memintanya secara eksplisit untuk memperluas alias, jadi ini juga akan berfungsi:
(Kasus di mana bash bersifat interaktif tidak memerlukan shell login , karena itu sudah cukup untuk membaca file inisialisasi, tetapi yang ini perlu
-l
membacanya.)Ini adalah baris perintah yang cukup panjang ... Dan mereka juga mengharuskan Anda mengutip seluruh perintah shell, jadi jika Anda memanggil alias dengan argumen, Anda harus mengubah semua itu menjadi string ... Jadi itu semacam kikuk untuk menggunakan ...
Perhatikan bahwa sebelumnya saya berbicara tentang alias dan fungsi ... Itu sengaja, karena fungsi sebenarnya jauh lebih nyaman di sini. Anda tidak perlu sesuatu yang istimewa (seperti memiliki shell interaktif, atau mengatur opsi tertentu) untuk menjalankan fungsi pada shell, selama Anda mencari definisi mereka.
Jadi, jika Anda mendefinisikan
ll
sebagai fungsi alih-alih alias, Anda dapat menggunakannya secara langsung dengan-i
pintasan sudo :Dan jika Anda memiliki baris perintah yang lebih panjang, dengan argumen, Anda bisa meneruskannya langsung di sini juga:
(Bandingkan dengan
sudo bash -i -c 'll -C -R /etc'
.)Fungsi juga jauh lebih fleksibel dan biasanya lebih mudah dipelihara ... Biasanya mudah untuk mengubah alias menjadi fungsi, satu-satunya peringatan adalah untuk selalu menggunakan di
"$@"
mana Anda mengharapkan argumen tambahan akan diambil (biasanya di akhir alias.)Misalnya, alias ini:
Dapat diubah menjadi fungsi ini:
Mereka, untuk sebagian besar tujuan, setara. Dan, seperti yang disebutkan sebelumnya, fungsi harus dapat diakses langsung dari
sudo -i
, jadi itu bonus tambahan.Saya harap Anda menemukan jawaban dan penjelasan ini bermanfaat!
sumber
sudo -i command arguments
untuk dapat menjalankan fungsi dari/root/.bashrc
dan telah mengekspor variabel yang tersedia. Tapi saya melihat bagaimana jawaban saya mungkin terlalu lama dan info itu agak terkubur di sana ... Jadi saya menambahkan TL; DR untuk meringkasnya (sambil tetap menyimpan rincian teknis penyelidikan sekitar.) Silakan lihat lagi.