Bagaimana cara menjalankan perintah 'sudo' di dalam skrip?

84

Untuk melakukan patch secara manual saya harus mengetik perintah ini

sudo ./playback_delete_data_patch.sh 09_delete_old_data_p.sql  

Ada ruang sebelum 09:

sudo ./playback_delete_data_patch.sh [space] 09_delete_old_data_p.sql

Bagaimana saya bisa menjalankan ini di dalam skrip?

Ada juga beberapa perintah lain tetapi ini memberikan masalah.

pengguna251948
sumber
2
Masukkan saja ke dalam skrip, apa masalahnya?
Lie Ryan
6
@LieRyan - sudo kata sandi - skrip tidak akan dapat berjalan sepenuhnya jika seseorang tidak ada di sana untuk memasukkannya.
Wilf
Sistem saya hanya menjalankannya dengan baik tanpa disuruh. Ubuntu 16.04 pada Oktober 2017. Anda telah mengacaukan sudoerspengaturan Anda . Bukan masalah besar. Itu hanya perlu diperbaiki.
SDsolar
1
@ SDolar Sistem Anda adalah salah satu yang kacau; itu adalah kerentanan keamanan kecil untuk tidak meminta kata sandi (membuat pengguna lebih rentan terhadap beberapa jenis serangan rekayasa sosial).
wizzwizz4

Jawaban:

107

Jarang ada ide bagus untuk memiliki sudoskrip dalam. Alih-alih, hapus sudodari skrip dan jalankan skrip itu sendiri dengan sudo:

sudo myscript.sh

Dengan begitu, semua perintah dalam skrip akan dijalankan dengan hak akses root dan Anda hanya perlu memberikan kata sandi sekali saat meluncurkan skrip. Jika Anda memerlukan perintah tertentu di dalam skrip untuk dijalankan tanpa sudohak istimewa, Anda dapat menjalankannya sebagai pengguna biasa dengan (terima kasih Lie Ryan ):

sudo -u username command 

Ruang tidak relevan, seharusnya tidak mempengaruhi apa pun, selalu ada ruang antara perintah dan argumennya.

terdon
sumber
30
mungkin ada perintah dalam skrip yang tidak memerlukan hak akses root, Anda dapat menghentikan hak root untuk sementara untuk perintah-perintah tersebut dengan menggunakan sudo -u nama pengguna
Lie Ryan
48
Banyak skrip yang saya tulis melakukan banyak interaksi pengguna dan / atau pengecekan kesalahan. Maka satu perintah di akhir - sesuatu seperti rsync - perlu dijalankan sebagai root. Mengapa saya ingin membuat semuanya berjalan lebih tinggi dan membiarkan diri saya terbuka untuk banyak baris kode yang dapat mengandung kesalahan serius atau kerentanan dengan akses root - terutama saat debugging - ketika hanya satu atau beberapa perintah yang memerlukan akses itu?
Joe
2
@ Jo cukup adil. Mengubah "tidak pernah menjadi ide yang baik" menjadi "jarang".
terdon
10
@ Jo punya poin bagus di sini. Juga ketika seseorang berkata jangan lakukan itu , akan menyenangkan untuk mengetahui persis mengapa itu, atau setidaknya, dalam konteks mana saya tidak boleh melakukan itu, dan mengapa
arainone
10
@terdon Anda tidak mendengarkan. Saya tahu bahwa jika Anda menjalankan skrip sebagai root, itu tidak akan pernah meminta Anda untuk sudo. Saya membandingkan bahwa dengan tidak menjalankan skrip sebagai root dan alih-alih menempatkan sudopanggilan eksplisit dalam skrip, karena meninggikan seluruh skrip ke root mungkin merupakan ide yang mengerikan jika hanya ada beberapa tindakan sempit yang perlu di-root. Dalam konteks itu saya merespons komentar Anda secara khusus: "Sebagian besar karena ini berarti Anda tidak dapat menjalankan skrip secara otomatis karena Anda harus memasukkan kata sandi setiap kali Anda ditanya."
BeeOnRope
41

Anda dapat memodifikasi sudoersfile.

Lari sudo visudo.

Tambahkan entri untuk nama pengguna Anda dan skrip yang ingin Anda jalankan tanpa diminta kata sandi.

username ALL=(ALL) NOPASSWD: /path/to/script
Klaus-Dieter Warzecha
sumber
2
Tidak bekerja untuk saya, tetapi terima kasih, senang mengetahui ini ada. Mungkin saya salah sintaks.
Chris K
5
Tidak yakin ada yang menyebutkannya, tetapi Anda harus menghentikan semua sesi login pengguna itu setelah Anda mengedit sudoersfile.
escape-llc
1
Hanya untuk memperjelas di sini, bukan skrip yang berisi "sudo ./playback_delete_data_patch.sh 09_delete_old_data_p.sql" baris yang harus ditentukan dalam file sudoers tetapi skrip playback_delete_data_patch.sh atau perintah lain apa pun yang Anda inginkan kepada pengguna dan / atau perintah mereka. skrip untuk dapat dijalankan melalui sudo tanpa menentukan kata sandi.
MttJocy
19

Anda dapat mencoba sesuatu seperti:

echo "PASSWORD" | sudo -S ./playback_delete_data_patch.sh 09_delete_old_data_p.sql

Ini bukan hal yang paling aman untuk dilakukan karena Anda menulis kata sandi sudoer dalam teks biasa. Untuk membuatnya sedikit lebih aman Anda bisa membuat variabel dan membaca kata sandi sudo ke dalam variabel dan kemudian Anda bisa menjalankan perintah sebagai:

echo $PASSWORD | sudo -S ./playback_delete_data_patch.sh 09_delete_old_data_p.sql

Juga, jika Anda tidak keberatan semua perintah Anda dijalankan sebagai root, Anda dapat dengan mudah mengeksekusi skrip Anda menggunakan sudo, seperti yang disarankan sebelumnya.

sudo ./myscript
Celoteh
sumber
Membaca kata sandi ke dalam variabel dengan aman:read -s PASSWORD
Tobias Uhmann
10

Jawaban ini mirip dengan jawaban terdon . Saya juga menyarankan untuk menjalankan skrip utama sudoagar skrip dapat berjalan tanpa harus meminta kata sandi pengguna selama eksekusi.

Namun, jika Anda ingin menghapus hak root untuk beberapa perintah dan menjalankannya sebagai pengguna sebenarnya yang dipanggil dengan perintah sudo, Anda dapat memeriksa $SUDO_USERvariabel untuk mencari tahu pengguna asli.

Ini adalah contoh skrip tentang bagaimana Anda dapat mencapai itu:

#!/bin/bash

# ref: https://askubuntu.com/a/30157/8698
if ! [ $(id -u) = 0 ]; then
   echo "The script need to be run as root." >&2
   exit 1
fi

if [ $SUDO_USER ]; then
    real_user=$SUDO_USER
else
    real_user=$(whoami)
fi

# Commands that you don't want running as root would be invoked
# with: sudo -u $real_user
# So they will be run as the user who invoked the sudo command
# Keep in mind if the user is using a root shell (they're logged in as root),
# then $real_user is actually root
# sudo -u $real_user non-root-command

# Commands that need to be ran with root would be invoked without sudo
# root-command
Dan
sumber
4

Sebenarnya ada cara yang lebih sederhana untuk melakukan ini. Untuk portabilitas, ini adalah implementasi saya tetapi merasa bebas untuk memanipulasinya sesuai dengan kebutuhan Anda.

Masukkan kata sandi sudo Anda sebagai parameter saat memulai skrip, tangkap, dan gema dengan setiap perintah yang akan meminta kata sandi sudo.

#!/bin/bash

PW=$1
echo $PW | ./playback_delete_data_patch.sh 09_delete_old_data_p.sql  
./command_wo_sudo.sh <param>
echo $PW | ./other_command_requires_sudo.sh <param>

Anda dapat menambahkan prompt dan menangkap setelah skrip dimulai seperti:

echo "enter the sudo password, please"
read PW

Tetapi jika orang lain memantau apa yang berjalan pada node; memiliki akses ke log yang dibuat olehnya; atau hanya memeriksa Anda secara acak ketika Anda menjalankan tes, yang dapat membahayakan keamanan.

Ini juga berfungsi dengan menjalankan perintah / skrip yang memerlukan ya untuk melanjutkan:

echo $PW | yes | ./install.sh

Gema sebagai respons terhadap prompt, sehingga Anda dapat menggunakan apa pun yang Anda butuhkan, di sana, jika Anda menjalankan skrip lain yang memiliki permintaan untuk kemajuan, secara berurutan. Namun, pastikan Anda tahu bahwa ketertiban atau hal-hal buruk dapat terjadi.

csworenx
sumber
Itu jauh lebih elegan dan sederhana, saya senang saya menggulung sampai ke bawah! Sunting: tunggu, ini akan menambah kata sandi ke riwayat terminal saya
Job
1
Bagaimana cara menanyakan nama pengguna / kata sandi dengan read: ryanstutorials.net/bash-scripting-tutorial/bash-input.php Itu harus menghindari masalah ini
Ayub
3
#!/bin/bash
# this declares that current user is a sudoer
sudo tee /etc/sudoers.d/$USER <<END
END

# write the content of your script here
sudo npm install hexo-cli -g
mkdir Untitled
sudo apt-get install python

# then to remove the sudo access from the current user
sudo /bin/rm /etc/sudoers.d/$USER
sudo -k
Sanyam Jain
sumber
0

Anda bisa mencoba menambahkan pengguna yang menjalankan skrip ke file sudoers:

#give permissions to the file
sudo chmod 700 /etc/sudoers.d/useradm

sudo visudo /etc/sudoers.d/useradm

#add the following text, changing "user" but your desired user
user ALL=(ALL)NOPASSWD:ALL

#return the right permissions to the file
sudo chmod 440 /etc/sudoers.d/useradm
evinhas
sumber
Umumnya ini adalah metode yang buruk. Jika Anda akan menambahkan aturan sudo NOPASSWD, terutama untuk akun yang menjalankan otomasi, Anda setidaknya harus membatasi mereka ke perintah yang dijalankan (dan bukan SEMUA)
Christopher Hunter