Neden bir kabuk betiğindeki “sudo su”, betiğin geri kalanını root olarak çalıştırmıyor?


36

Örnek bir komut dosyası aşağıdaki gibi olabilir:

#!/bin/bash
sudo su
ls /root

./test.shNormal kullanıcı olarak kullanıldığında , bunun yerine lssüper kullanıcı olarak çalıştır ve çıkar, o root'a geçer; ve oturumu kapattığımda ls /rootnormal kullanıcı olarak çalışıyor.

Biri bana mekanizma hakkında bir şey söyleyebilir mi?


13
sudo sugözlerimi acıtıyor.
gelraen

Çünkü insanlar yeterince sudo bilmiyorlar ve kökün kasıtlı olarak bozulmuş bir parola ile güvence altına alındığı sistemler üzerinde çalışacak bir yola ihtiyaç duyuyorlar. Ama evet sudo su kullanımını "reddedified".
Johan

1
sudo -sYine de kullanamaz mısın?
Joe Z.

@Johan, sık sık kullanıyorum sudo suçünkü tercihleriminkinden sudaha fazla alışkınım sudo. Sudo'nun seçeneklerini yeterince iyi biliyorum, ancak daha hızlı olanları yazabiliyorum. Ama evet sanırım bu yeterince iyi sudo bilmediğim anlamına geliyor.
user606723

1
Az önce sudo man sayfasını kontrol ettim. Görünür O sudo -iile benzerlik göstermektedir su -iken sudo -sgibi çalışır su(dash olmadan)
Johan

Yanıtlar:


49

Bir komut dosyasındaki komutlar bağımsız olarak tek tek yürütülür. Komut Dosyasının kendisi, komut dosyasındaki tüm komutların üst öğesi olarak, başka bir bağımsız işlemdir ve su komutu onu kök dizinine değiştirmez ve değiştiremez: su komutu, kök ayrıcalıklarına sahip yeni bir işlem oluşturur.

Bu su komutu tamamlandıktan sonra, hala aynı kullanıcı olarak çalışan ana işlem, komut dosyasının geri kalanını yürütür.

Yapmak istediğin bir sarmalayıcı komut dosyası yazmak. Ayrıcalıklı komutlar, örneğin ana komut dosyasına girer.~/main.sh

#!/bin/sh
ls /root

Sarıcı komut dosyası, ana komut dosyasını bunun gibi kök izinleriyle çağırır.

#!/bin/sh
su -c ~/main.sh root

Bu işlemi başlatmak için, sırayla kullanıcıyı kök kullanıcıya geçirdikten sonra ana betiği açan sarmalayıcıyı çalıştırırsınız.

Bu sarmalayıcı tekniği, senaryoyu kendi etrafındaki bir sarmalayıcıya dönüştürmek için kullanılabilir. Temel olarak root olarak çalışıp çalışmadığını kontrol edin, eğer değilse, kendini yeniden başlatmak için "su" kullanın.

$ 0, bir senaryoyu kendisine ifade etmenin kullanışlı bir yoludur ve whoami komutu bize kim olduğumuzu söyleyebilir (biz kök mü?)

Böylece yerleşik sargılı ana komut dosyası

#!/bin/sh
[ `whoami` = root ] || exec su -c $0 root
ls /root

Exec kullanımına dikkat edin. "Bu programın yerine geçme" anlamına gelir; bu, yürütmeyi etkili bir şekilde sonlandırır ve su tarafından başlatılan yeni bir programı kökten çalıştırmaya başlar. Değişim örneği "root" dır, bu yüzden ||


1
fwiw, bu noktada bir zeyilname. Eğer böyle bir senaryo yazıyorsam, başlangıçta $ EUID'yi kontrol eden bir if if ifadesi yapardım ve eğer sıfır sudo değilse ve çıkmazsa, komut dosyası işlemine devam edin.
Bratchley

Kabul etti ve bunu açıklamak için cevabı güncelleyeceğim.
Johan

2
Belki biraz arkaik ama ben her çalıştırılabilir için mutlak yolları seviyorum, bu yüzden birisi ~ / main.sh betiğini nefret dolu bir şey haline getiremez. Senaryonun KULLANICI kısmına saldırmak
artifex

2
Ayrıca, $ *
Bratchley

@JoelDavis Daima "argümanlarda boşluk karakteri varsa" duvarına rastlarım. Hiç tatmin edici bir çözüm bulamadım. Bir zamanlar bir argümanını geçici bir dosyaya koyan bir komut dosyası yazdım, her satırda bir argüman ve sonra neye ihtiyaç duyduğunu seçti ve o son yazıya orijinal argümanları bulmak için hangi dosyanın okunacağının argümanını iletti.
Johan

20

Aşağıdaki komut dosyasını kullanın.

sudo su <<HERE
ls /root
HERE

HERE bloğu arasındaki kod root olarak çalıştırılacaktır.


6
sudo suiki program çağırıyor. Kullanın sudo -s <<HEREDOCveya su user <<HEREDOC... Aptal 5 dakikalık limit.
Johan

6

Daha fazla argüman olmadan su, giriş kabuğunu root için çalıştıracak. Senaryonuzun ilk satırı gerçekte böyle yapar. Eğer, giriş kabuğu kapanır, su döner çıkmak ve komut ikinci satırla olduğunu, yürütme devam ettiğinde: ls /root. Sanırım istediğini yapabilirsin sudo ls /root.


Evet, bunun için yapabileceğimi biliyorum ls, ama bu sadece bir örnek. Aslında, kök ayrıcalığına sahip çok daha fazla şey yapmam gerekiyor :-) Bu yüzden @ Ankit'in cevabını tercih ediyorum.
Hongxu Chen,

1

Eğer ateş kez sudo suetkili olan yeni bir süreç userid (euid=EUID)çatallı Süper kullanıcının, dolayısıyla farklı işlem kimliği çalışan yeni bash (pid=PID)aynı terminal ile ilişkili (tname=TTY).

açıklama

Atış sonrası varsayalım ps -A | grep bashsahip 21460 pts/2 00:00:00 bashçıktı olarak. Şimdi, ./test.shher iki komutu da çalıştırdığınızda sudo suve ls /rootbiriktirileceksiniz PID 21460. Yürütmeden sonra root, aktif bir kullanıcı olarak ps -A | grep bashtekrar vurduğunuzda , devam eden yeni bir bash fark edeceksiniz PID say, 21570. Çıkılması root bashgeri dönerek yeni bash çatallı öldürecek olduğum user's bashdolayısıyla ve biriktirilir komutu çalıştırır ls /rootistemi bırakmadan önce.


Su veya sudo kullanmak bash'te (veya başka bir yerde) "kalıcı" olsaydı, çözdüğünden çok daha fazla problem yaratabilirdi. Güvenlik ve emniyet için mümkün olan en az kökü yapmanız gerekir. Su ve sudoya sahip olmanın asıl amacı (güvenlik dışında!), Kök ayrıcalıklara ihtiyaç duyduğunuz şeyleri dikkatlice düşünmenizi sağlamaktır.
Joe,
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.