Bir sudo ile bir komut satırı çalıştır


21

Örneğin, bir dosya oluşturmak ve bir satırda metin girmek istersem, >işleci kullanarak çıktıyı bir dosyaya yönlendirebilirim :

echo "something" > /path/foobar

ancak klasöre erişemezsem /path/ve sudo ayrıcalıklarına ihtiyacım varsa, sudo haklarına sahip normal bir kullanıcı olarak bu komutu nasıl başarabilirim?

denedim

sudo echo "something" > /path/foobar

ama bu, işi değildir çünkü için sudo sadece sayıları editdeğil, sağ kısmı
arasında>

Tabi, önce ile kökleşebilir sudo suveya teeonun yerine kullanabilirim :

echo "something" | sudo tee /path/foobar

Fakat son hat ile çalışabileceğim bir çözüm bulmak istiyorum.

sudo !!

Son satırı "geri dönüştürmek" ve sadece eklemek için bir yol yok sudomu?



Bu bir kopya değil. Gerçek Qeustion'u çıkardım ve başlığı değiştirdim. Şimdi gerçekten aradığım şey bu
rubo77

Kesinlikle oldu yinelenen, ama şimdi biraz farklıdır. Bana, soruyu Boogy'nin cevabı ışığında yeniden yazdığınız gibi görünüyor, bu iyi - bu iyi bir cevap. Yakın oyumu geri çektim, ancak yine de kaçınılmaz (bir soru, konuyu dikkate almadan bir soru yakın sırada olduğunda otomatik olarak oy kullanmaktadır): kapalı olduğunda ve tekrar açmak için oy kullanacağım bir yorumu yazın . Davanızı, bir kez meydana geldiğinde sohbette kabul edebilirsiniz .
goldilocks

Yanıtlar:


13

Sadece sudobir kabuk komutunun önüne yapıştıramazsınız , bu komutu tekrar değerlendirmek için bir kabuk çağırmanız gerekir (değişkenleri genişletmek, yeniden yönlendirme operatörleri için dosyaları açmak, vb.). Yani bu

sudo bash -c !!

Bunun dışında pek çalışmaz, çünkü !!önceki komutun metnini, özel karakterleri ve hepsini enterpolasyon yapar . Komut metnini bir dize olarak almanız ve bunu bir argüman olarak iletmeniz gerekir sh. Neyse ki, bash'ın fcyerleşik yapısı bunu yapmanıza izin veriyor¹.

sudo bash -c "$(fc -ln -1)"

Hatta şu anda çalışan bash sürümünün aynı olduğundan emin olmak için:

sudo "$BASH" -c "$(fc -ln -1)"

Komutun ayrı bir kabuk işleminde yürütüldüğünden, ortam değişkenlerini (sadece koruyanları dikkate alarak) devraldığını sudo, ancak iç değişkenleri kabuk almadığını unutmayın. Kabuk seçenekleri (örneğin kshglob) ve diğer ayarlar da varsayılandan başlayacaktır.

ATT ksh93 hem de gerektirir ama aynı command², zsh ve ksh çalışır firstve lastsayısı geçirilecek fcbasınız → (aynı zamanda bash çalıştığı, zsh ve pdksh / mksh):

sudo zsh -c "$(fc -ln -1)"
sudo ksh -c "$(fc -ln -1 -1)"
sudo "$0" -c "$(fc -ln -1 -1)"

$0Çalışan kabuğun çalıştırılabilirini tanımlamak için kullanmak , yalnızca kabuk $ PATH aracılığıyla ve $ PATH değişmemişse veya mutlak bir yol boyunca çalıştırıldığında çalışır.

İşte biraz daha net ama daha uzun olan zsh içindeki başka bir yöntem:

sudo zsh -c $history[$[HISTCMD-1]]

Son bir uyarı kelimesi: sudopotansiyel olarak tehlikeli komutlar içindir. Kullanımı çok kolay hale getirme!

¹ Orada bazı ekstra boşluk başında bulunuyor ve komut ikamesi sonunda yeni satır kapalı şeritler, fakat kabuğun sözdizimi bu umurumda değil.
² zsh ya da ksh'ın bash gibi bir şeye sahip olduğunu sanmıyorum $BASH; $0yalnızca mutlak bir yol olduğunda veya eğik çizgi içermediğinde ve komut arama yolu değişmediğinde çalışır.
T ATT ksh için bir takma addır, ancak bu kadar iyidir. fchist


9

Aynı komutu sudo ile tekrarlamak istiyorsanız !! böyle bir komut yaptıktan sonra:

echo "something">/path/file

Komutu geri çağırmak için global change sözdizimini kullanıyorsunuz:

!!:gs/>/|sudo tee -a /

-A parametresinden sonra bir boşluk kullanın .

Bu sudo eşdeğeridir !! ancak <ve> için sudo kısıtlamalarını atlamanıza yardımcı olur. Çünkü sudo, [<,>] kullanmana izin vermiyor.


Yönlendirmeler için genel olarak sudo kısıtlamalarını atlamak için, bunu şöyle kullanabilirsiniz:

echo "something" | sudo tee myfile

tee komutu standart girdiden okuma yapmanıza ve standart çıktıya ve dosyalara yazmanıza izin verir

Komutu tekrarlamak ve dosyaya bir metin eklemek istiyorsanız, tee komutunun eklemek için -a seçeneği vardır . Böylece emri hatırlayabilirsin

sudo !!

ve metin dosyaya eklenecektir

örnek:

echo "something" | sudo tee -a /path/file
sudo !!

güzel bir çözüm, ama ezberlemek biraz zor. Kullanarak bir komut için nasıl bir takma ad oluşturabilirim !! son komutu hatırlamak için ?
rubo77

olduğunu -agerçekten gerekli? >bir dosyanın üzerine tee -a>>
yazacak

3

Bu kadar basit gibi görünüyor sudo sh -c "!!":

$ cd /
$ echo hello > foo
bash: foo: Permission denied
$ sudo sh -c "!!"
sudo sh -c "echo hello > foo"
$ ls -l foo
-rw-r--r-- 1 root root 6 Jun 20 16:21 foo

3
Komut tırnak işaretleri kullanıyorsa, bunun mutlaka aynı olması gerekmez. Düşünün echo "foo bar"haline getirme sh -c "echo "foo bar""sadece yazdırmak hangi fooyerine foo bar.
godlygeek

sudo sh -c '!!'
Emrinizde

Peki ya emriniz hem tek hem de çift tırnak işareti kullanıyorsa? Veya çift tırnak ve değişken açılımlar? Eğer kullanıcı yaptıysa: a=bve sonra echo "$a" >fileve sonra içine boş bir satır basacak şekilde sudo sh -c '!!'genişleyecekti . sudo sh -c 'echo $a >file'bfile
godlygeek

Yani belki bir şekilde daha iyi bir çözüm var?
rubo77

1
Komutu değiştirmek zorunda kalmadan zamanın% 100'ünü çalıştıracak bir çözüm olduğunu sanmıyorum. Kullanılması sudokomutu kök olmayan kabuğunda kuruldu kullanım değişkenleri bekleniyordu eğer bir kök kabuğu almak ve daha sonra kopyalama ve en yakın olurdu içine komutu yapıştırarak, ancak başarısız olur. sudo sh -c "!!"Eserleri basit komutlar için iyi kullanmak , ancak karmaşık olanlar için doludur. En iyi tavsiyenin, zamanın% 100'ünde işe yarayacak bir komut olmasını beklememek olduğunu düşünüyorum - bazı olası çözümler öğrenin ve her birini en uygun olduğu zaman uygulayın.
godlygeek
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.