Saya memiliki skrip yang melakukan sejumlah hal yang berbeda, yang sebagian besar tidak memerlukan hak khusus. Namun, satu bagian spesifik, yang saya isi di dalam suatu fungsi, membutuhkan hak akses root.
Saya tidak ingin mengharuskan seluruh skrip dijalankan sebagai root, dan saya ingin dapat memanggil fungsi ini, dengan hak akses root, dari dalam skrip. Meminta kata sandi jika perlu bukanlah masalah karena sebagian besar bersifat interaktif. Namun, ketika saya mencoba menggunakan sudo functionx
, saya mendapatkan:
sudo: functionx: command not found
Seperti yang saya harapkan, export
tidak ada bedanya. Saya ingin dapat menjalankan fungsi secara langsung dalam skrip alih-alih memecahnya dan menjalankannya sebagai skrip terpisah karena sejumlah alasan.
Apakah ada cara agar fungsi saya "terlihat" oleh sudo tanpa mengekstraknya, menemukan direktori yang sesuai, dan kemudian menjalankannya sebagai skrip yang berdiri sendiri?
Fungsinya sekitar satu halaman sendiri dan berisi banyak string, beberapa kutip ganda dan beberapa kutip tunggal. Ini juga tergantung pada fungsi menu yang didefinisikan di tempat lain dalam skrip utama.
Saya hanya berharap seseorang dengan sudo ANY untuk dapat menjalankan fungsi, karena salah satu hal yang dilakukannya adalah mengubah kata sandi.
declare
mereka juga.Jawaban:
Saya akan mengakui bahwa tidak ada cara sederhana dan intuitif untuk melakukan ini, dan ini sedikit hackey. Tapi, Anda bisa melakukannya seperti ini:
Atau lebih sederhana:
Ini bekerja untuk saya:
Pada dasarnya,
declare -f
akan mengembalikan konten fungsi, yang kemudian Anda sampaikan kebash -c
inline.Jika Anda ingin mengekspor semua fungsi dari instance luar bash, ubah
FUNC=$(declare -f hello)
keFUNC=$(declare -f)
.Edit
Untuk membahas komentar tentang mengutip, lihat contoh ini:
sumber
echo "Hello!"
secara efektif sama denganecho Hello!
(yaitu tanda kutip ganda tidak membuat perbedaan untuk perintah gema khusus ini). Dalam banyak / sebagian besar keadaan lain, tanda kutip ganda dalam fungsi cenderung melanggarbash -c
perintah.bash -xc
bukan hanyabash -c
) dan sepertinyabash
cukup pintar untuk re-quote hal dalam situasi ini, bahkan sampai penggantian tanda kutip ganda dengan tanda kutip tunggal dan mengubah'
untuk'\''
jika perlu. Saya yakin akan ada beberapa kasus yang tidak bisa ditangani, tetapi pasti berfungsi untuk setidaknya kasus sederhana dan cukup kompleks - misalnya cobafunction hello() { filename="this is a 'filename' with single quotes and spaces" ; echo "$filename" ; } ; FUNC=$(declare -f hello) ; bash -xc "$FUNC ; hello"
declare -f
print definisi fungsi dengan cara yang dapat re-diurai oleh bash, sehinggabash -c "$(declare -f)"
tidak bekerja dengan benar (dengan asumsi bahwa kulit luar juga bash). Contoh yang Anda poskan menunjukkannya berfungsi dengan benar - di mana tanda kutip diubah ada dalam jejak , karena bash mencetak jejak dalam sintaksis shell, mis. Cobabash -xc 'echo "hello world"'
sudo yourFunction
tidak ditemukan (jika tidak Anda mendapatkan kesalahan segmentasi dari rekursi)"Masalahnya" adalah yang
sudo
membersihkan lingkungan (kecuali beberapa variabel yang diizinkan) dan menetapkan beberapa variabel ke nilai aman yang telah ditentukan sebelumnya untuk melindungi dari risiko keamanan. dengan kata lain, ini sebenarnya bukan masalah. Itu fitur.Misalnya, jika Anda menetapkan
PATH="/path/to/myevildirectory:$PATH"
dansudo
tidak menetapkan PATH ke nilai yang ditentukan sebelumnya, maka skrip apa pun yang tidak menentukan pathname lengkap untuk SEMUA perintah yang dijalankannya (yaitu sebagian besar skrip) akan mencari/path/to/myevildirectory
sebelum direktori lain. Masukkan perintah sepertils
ataugrep
atau alat umum lainnya di sana dan Anda dapat dengan mudah melakukan apa pun yang Anda suka di sistem.Cara termudah / terbaik adalah menulis ulang fungsi sebagai skrip dan menyimpannya di suatu tempat di path (atau menentukan path lengkap ke skrip pada
sudo
baris perintah - yang perlu Anda lakukan kecuali jikasudo
dikonfigurasi untuk memungkinkan Anda untuk menjalankan perintah APA SAJA sebagai root), dan membuatnya dapat dijalankan denganchmod +x /path/to/scriptname.sh
Menulis ulang fungsi shell sebagai skrip sesederhana hanya menyimpan perintah di dalam definisi fungsi ke file (tanpa
function ...
,{
dan}
baris).sumber
sudo -E
hindari membersihkan lingkungan.Saya telah menulis
Sudo
fungsi bash saya sendiri untuk melakukan itu, berfungsi untuk memanggil fungsi dan alias:sumber
Anda dapat menggabungkan fungsi dan alias
Contoh:
lalu
sudo hello
bekerjasumber
Berikut variasi jawaban Will . Ini melibatkan
cat
proses tambahan , tetapi menawarkan kenyamanan heredoc. Singkatnya bunyinya seperti ini:Jika Anda ingin lebih banyak makanan untuk dipikirkan, coba ini:
Outputnya adalah:
Di sini kita punya
menu
fungsi yang sesuai dengan yang ada di pertanyaan, yang "didefinisikan di tempat lain dalam skrip utama". Jika "di tempat lain" berarti definisinya telah dibaca pada tahap ini ketika fungsisudo
yang diminta dijalankan, maka situasinya analog. Tapi itu mungkin belum dibaca. Mungkin ada fungsi lain yang belum memicu definisinya. Dalam haldeclare -f menu
ini harus diganti dengan sesuatu yang lebih canggih, atau seluruh skrip dikoreksi sedemikian rupa sehinggamenu
fungsinya sudah dinyatakan.sumber
menu
fungsi akan dideklarasikan sebelum titik ini, sepertif
yang dipanggil dari menu.Dengan asumsi bahwa skrip Anda (a) mandiri atau (b) dapat mengambil komponennya berdasarkan lokasinya (daripada mengingat di mana direktori home Anda), Anda dapat melakukan sesuatu seperti ini:
$0
pathname untuk skrip, gunakan itu dalamsudo
perintah, dan berikan opsi yang skrip akan periksa, untuk memanggil pembaruan kata sandi. Selama Anda mengandalkan menemukan skrip di path (bukan hanya menjalankan./myscript
), Anda harus mendapatkan pathname absolut di$0
.sudo
menjalankan skrip, ia memiliki akses ke fungsi yang diperlukan dalam skrip.uid
dan menyadari bahwa skrip tersebut dijalankan sebagai pengguna root , dan melihat bahwa ia memiliki opsi yang ditetapkan untuk memberi tahu itu untuk memperbarui kata sandi, pergi dan lakukan bahwa.Naskah dapat muncul kembali dengan sendirinya karena berbagai alasan: mengubah hak istimewa adalah salah satunya.
sumber