Bir komut dosyasında 'sudo' komutunu nasıl çalıştırırım?


84

Bir yamayı elle yapmak için bu komutu yazmam gerekiyor

sudo ./playback_delete_data_patch.sh 09_delete_old_data_p.sql  

09'dan hemen önce bir boşluk var:

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

Bunu bir komut dosyasında nasıl çalıştırabilirim?

Başka komutlar da var ama bu sorun veriyor.


2
Sadece senaryoya yaz, sorun ne?
Yalan Ryan

6
@LieRyan - sudo şifre - birileri girmek için orada değilse, komut dosyası tam olarak çalışamaz.
Wilf

Sistemim sormadan sadece onları iyi çalışır. Ekim 2017'de Ubuntu 16.04. sudoersKurulumunuzu berbat ettiniz . Önemli değil. Sadece düzeltilmesi gerekiyor.
SDsolar

1
@SDsolar Kişisel sisteminin berbat bir şey biridir; şifre sorulmaması küçük bir güvenlik açığıdır (kullanıcıları bazı sosyal mühendislik saldırılarına karşı daha savunmasız hale getirir).
wizzwizz4

Yanıtlar:


107

sudoİçinde senaryoların olması nadiren iyi bir fikirdir . Bunun yerine, sudokomut dosyasını kaldırın ve komut dosyasını kendisiyle çalıştırın sudo:

sudo myscript.sh

Bu şekilde, komut dosyasındaki tüm komutlar kök ayrıcalıklarıyla çalıştırılır ve komut dosyasını başlatırken yalnızca bir kez şifre vermeniz gerekir. Senaryo içerisinde sudoimtiyazlar olmadan çalıştırılmak için belirli bir komuta ihtiyacınız olursa , bunu normal bir kullanıcı olarak çalıştırabilirsiniz ( Lie Lie sayesinde ):

sudo -u username command 

Boşluk alakasız, hiçbir şeyi etkilememeli, bir komutla argümanları arasında daima bir boşluk vardır .


30
komut dosyasında, kök ayrıcalığına ihtiyaç duymayan komutlar olabilir, sudo -u kullanıcı adınızı kullanarak bu komutlar için kök ayrıcalıklarını geçici olarak bırakabilirsiniz
Lie Ryan

48
Yazdığım birçok komut bir sürü kullanıcı etkileşimi ve / veya hata kontrolü yapıyor. Sonra sonunda bir komut - rsync gibi bir şey - root olarak çalıştırılması gerekir. Neden her şeyin yükseltilmesini sağlamak ve kendimi root erişimi ile ilgili ciddi hatalar veya güvenlik açıkları içerebilecek - özellikle hata ayıklama sırasında - yalnızca bir veya birkaç komut bu erişimi gerektirdiğinde çok fazla kod satırına açık bırakmak isteyeyim?
Joe

2
@Joe yeterince adil. "Hiçbir zaman iyi bir fikir" olarak "nadiren" olarak değiştirildi.
terdon

10
@Joe burada gerçekten iyi bir noktaya sahip. Ayrıca biri bunu yapmadığını söylediğinde , bunun neden olduğunu veya en azından hangi bağlamda bunu yapmamam gerektiğini ve nedenini bilmek güzel olurdu
arainone

10
@ terdon Dinlemiyorsunuz. Ne olursa biliyorum root olarak komut dosyasını çalıştırın o sudo isteyecektir asla. Ben sadece betiği root olarak çalıştırmamak ve betiğe açık sudoçağrılar koymakla karşılaştıracağım , çünkü betiğin tamamını root'a yükseltmek, root gerektiren sadece bir avuç kadar az eylem varsa, korkunç bir fikir olabilir. Bu bağlamda yorumunuza özellikle cevap veriyordum: "Büyük ölçüde çünkü bu, sizden her istendiğinde şifreyi girmeniz gerekeceğinden betiği otomatik olarak çalıştıramayacağınız anlamına gelir."
BeeOnRope

41

Dosyayı büyük olasılıkla değiştirebilirsiniz sudoers.

Run sudo visudo.

Kullanıcı adınız ve bir şifre sormadan çalıştırmak istediğiniz komut dosyası için bir giriş ekleyin.

username ALL=(ALL) NOPASSWD: /path/to/script

2
Benim için işe yaramadı, ama teşekkürler, bunun var olduğunu bilmek güzel. Belki de sentaksı yanlış anladım.
Chris K,

5
Kimsenin bundan bahsettiğinden emin değilim, ancak sudoersdosyayı düzenledikten sonra o kullanıcının tüm oturumlarını sonlandırmanız gerekir .
kaçış-llc

1
Sadece burada açıklığa kavuşturmak için, sudoers dosyasında belirtilmesi gereken "sudo ./playback_delete_data_patch.sh 09_delete_old_data_p.sql" satırını içeren komut dosyası değil, bu kullanıcı ve / veya onların komutunu istediğiniz başka bir komut veya Bir şifre belirtmeden sudo ile çalışabilmek için komut dosyaları.
MttJocy

19

Gibi bir şey deneyebilirsiniz:

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

Düz metinle bir sudoer şifresi yazdığınızdan bu, yapılacak en güvenli şey değildir. Biraz daha güvenli hale getirmek için bir değişken oluşturabilir ve sudo şifresini değişkene okuyabilir ve ardından komutu aşağıdaki gibi çalıştırabilirsiniz:

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

Ayrıca, tüm komutlarınızın root olarak çalıştırılmasının sakıncası yoksa, betiğinizi sudodaha önce önerildiği şekilde kullanarak kolayca çalıştırabilirsiniz .

sudo ./myscript

Şifreyi güvenli bir şekilde güvenli bir şekilde okuma:read -s PASSWORD
Tobias Uhmann

10

Bu cevap Terdon en benzer cevap . Ayrıca ana betiği birlikte çalıştırmanızı öneririm, sudoböylece komut dosyası yürütme sırasında kullanıcının şifresini sormaya gerek kalmadan çalıştırılabilir.

Bununla birlikte, bazı komutlara kök ayrıcalıklarını bırakmak ve onları komutu çağıran asıl kullanıcı olarak çalıştırmak isterseniz, asıl kullanıcıyı sudobulmak için $SUDO_USERdeğişkeni kontrol edebilirsiniz .

Bu, bunu nasıl başarabileceğinize dair örnek bir komut dosyasıdır:

#!/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

4

Bunu yapmanın çok daha basit bir yolu var. Taşınabilirlik için bu benim uygulamam ama ihtiyaçlarınızı karşılamak için kullanmakta özgürsünüz.

Komut dosyasını başlatırken sudo şifrenizi bir parametre olarak girin, yakalayın ve sudo şifresini isteyecek olan her komutla yankılanın.

#!/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>

Bir komut istemi ekleyebilir ve komut dosyası şu şekilde başlatıldıktan sonra yakalayabilirsiniz:

echo "enter the sudo password, please"
read PW

Fakat eğer birisi düğümde neyin çalıştığını izlerse; tarafından oluşturulan günlüklere erişimi vardır; ya da sadece bir test yaptığınızda, güvenliği tehlikeye atabilecek rastgele bir şekilde bakmaktır.

Bu, devam etmek için bir evet gerektiren çalışan komutlar / komut dosyaları ile de çalışır:

echo $PW | yes | ./install.sh

Yankı, bir isteme yanıt olarak gelir; böylece, ilerlemesini isteyen diğer komut dosyalarını sıralı bir sırayla çalıştırıyorsanız, ihtiyacınız olan her şeyi kullanabilirsiniz. Bu emri bildiğinizden emin olun, fakat kötü şeyler olabilir.


Bu çok daha zarif ve basit, sonuna kadar kaydırdığım için memnunum! EDIT: bekle, bu parola benim terminal geçmişime ekleyecektir
Job

1
Kullanıcı adı istemek için nasıl / şifre read: ryanstutorials.net/bash-scripting-tutorial/bash-input.php bu sorunu kaçınmalıdır
İş

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

0

Komut dosyasını çalıştıran kullanıcıyı sudoers dosyasına eklemeyi deneyebilirsiniz:

#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

Genellikle bu kötü bir yöntemdir. Özellikle otomasyon kullanan hesaplar için NOPASSWD sudo kuralları ekleyecekseniz, en azından bunları çalıştırılan tam komutla kısıtlamanız gerekir (TÜM değil)
Christopher Hunter
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.