~ / .Zshrc işlevinden sudo'ing işlevi “komut bulunamadı”


10

Benim bir işlevi var ~/.zshrc:

findPort() {
    lsof -t -i :$1
}

Her zamanki çağrı findPort 3306.

Yükseltilmiş ayrıcalıklarla çalıştırmak istiyorum. Ama "komut bulunamadı" mesajını alıyorum.

  git 🍔 sudo findPort 3306
sudo: findPort: command not found

Bunun nedeni, kök kullanıcının ya etkileşimli olmayan bir kabuk olarak çalıştığı (bu nedenle bir .zshrc'ye başvurmadığı) ya da farklı bir değere işaret ettiği varsayılmaktadır .zshrc.

Benzer sorular gördüm alias, ancak kullanıcı tanımlı işlevlerle ilgili hiçbir soru yoktu. Bu sorunun yanıtları aşağıdakilere aliastakma ad eklemeyi içerir ~/.zshrc:

alias sudo='nocorrect sudo '

Ya da belki:

alias sudo='sudo '

Bu çözümlerin her ikisini de denedim ve sorun hala var (evet kabuğu yeniden başlattım).

Ayrıca sudo chshkök kabuğumun altında çalışmasını sağlamak için çalışmayı denedim zsh. Bu çözümlerin hiçbiri "komut bulunamadı" sorununu gidermez.

Kullanıcı tanımlı işlevlerimi sudo altında çalıştırmanın bir yolu var mı?


Ayrıca bakınız: unix.stackexchange.com/questions/181414/… ( zsh'ın kendi hileleri olduğu için işaretlenmiyor)
muru

Yanıtlar:


13

sudodeğil bir kabuk aracılığıyla, doğrudan komutları çalıştırır ve bu komutu çalıştırmak için bir kabuk koştu bile, sizin okuyan biri yeni bir kabuk çağırma olacak ve olmaz ~/.zshrc(bir interaktif kabuk başlamış olsa bile, muhtemelen okurdum root's ~/.zshrc, değişkeni sudosıfırlamayacak şekilde yapılandırmadıkça sizinkini değil $HOME).

Burada, sudoyeni bir zshkabuk başlatmanızı ve bu işlevi çalıştırmadan önce zshbunu okumanızı söylemeniz gerekir ~/.zshrc:

sudo zsh -c '. $0; "$@"' ~/.zshrc findPort 3306

Veya:

sudo zsh -c '. $0; findPort 3306' ~/.zshrc

Veya şu anki zsh işlevlerinizi şu kişiler zshtarafından çağrılan yeni ile paylaşmak için sudo:

sudo zsh -c "$(functions); findPort 3306"

Tanımlanmış birçok fonksiyonunuz varsa (tamamlama sistemini kullanırken olduğu gibi) bir arg listesi çok uzun bir hata alabilirsiniz . Bu nedenle, findPortişlevi işlevle (ve varsa dayandığı diğer tüm işlevlerle) sınırlamak isteyebilirsiniz :

sudo zsh -c "$(functions findPort); findPort 3306"

Ayrıca şunları da yapabilirsiniz:

sudo zsh -c "(){$functions[findPort]} 3306"

3306 bağımsız değişkenini ilettiğiniz anonim bir işlevefindPort işlevin kodunu gömmek için . Ya da:

sudo zsh -c "$functions[findPort]" findPort 3306

(geçirilen içi komut -c olan fonksiyon gövdesi).

Aşağıdaki gibi bir yardımcı işlev kullanabilirsiniz:

zsudo() sudo zsh -c "$functions[$1]" "$@"

Kullanmayın:

sdo () {sudo zsh -c "() {$ fonksiyonlar [$ 1]} $ {@: 2}"}

Gibi argümanlar sdobaşka bir kabuk ayrıştırma seviyesi geçecek. Karşılaştırmak:

$ e() echo "$@"
$ sdo e 'tname;uname'
tname
Linux
$ zsudo e 'tname;uname'
tname;uname

Yazmak kadar kısa bir çözüme ihtiyacım var sudo. Anonim işlev çözümünüzü tam da bunu yapacak şekilde uyarlayabildim . Yükseltilmiş ayrıcalıklarla diğer işlevleri~/.zshrc çalıştırmak için bir işlev olan benim için aşağıdaki işlevi ekledim :sdo() { sudo zsh -c "(){$functions[$1]} ${@:2}" }
Birchlabs

1
@Birchlabs, bkz. Düzenleme
Stéphane Chazelas

Teşekkürler; Cevabınızı önerdiğiniz yeni kısayolu kullanmak için güncelledim.
Birchlabs

Sudo üzerinden yürütülen komut dosyasına işlev tanımı eklemek akıllıdır. Ancak bu işlev başka bir işlev kullanıyorsa (otomatik yüklendi veya yüklenmedi) yeterince akıllı değil.
Damien Flament

3

Benim için çok basit bir çözüm sudo -s, macsh ile birlikte gelen zsh (5.2) sürümümde çalışıyor gibi görünen etkileşimli bir kabuk çağırmaktı . Bu bana benim fonksiyonlarım sağlar ~/.zshrc.

Bu davranışa gerçekten ipucu vermeyen sudo man sayfasından:

-s, --shell
Ayarlanmışsa SHELL ortam değişkeni tarafından belirtilen kabuğu veya çağıran kullanıcının parola veritabanı girdisi tarafından belirtilen kabuğu çalıştırır. Bir komut belirtilirse, kabuğun -c seçeneği ile yürütmek üzere kabuğa geçirilir. Herhangi bir komut belirtilmezse, etkileşimli bir kabuk yürütülür.

Kullanım durumunuzun ne olduğundan emin değilim, ancak etkileşimli bir çözüm aradığınızdan şüpheleniyorum.


Bu gerçekten işe yarıyor. Gerçi aklımdaki iş akışı tam olarak değil. Arzum, her zamanki kullanıcı gibi bir istemde kalmak ve sadece kullanıcı tanımlı işlevimi myFunc, yazarak sudo myFuncyükseltmek - aynı şekilde herhangi bir işlemi (örneğin sudo rm -rf .) yükseltirim . Bu çözüm, istemimin tamamını ve gelecekteki tüm işlevleri yükseltir, ayrıca gelecekteki tüm işlevler için kullanıcımı değiştirir - ki bu biraz abartılıdır.
Birchlabs

sudo -sKomut süper kullanıcı olarak kabuğundan başka örneğini başlatacak. Bu komutu etkileşimli olarak yürütürseniz, yeni kabuğunuz etkileşimli olur. Ancak komut , süper kullanıcı olarak kabuğunuzdaki sudo -s findPort 3306komutu çalıştıracak ve findPort 3306daha sonra bu komutun durum koduyla çıkacaktır.
Damien Flament

2

Ben yeniden kullanılabilir üretmek mümkün oldu steno Stéphane Chazelas' açıklanan çözümlerin biri için cevap . [Düzenle: Stéphane önerdiğim orijinal kısayolu yineledi; burada açıklanan kod onun yapımının daha yeni bir sürümüdür]

Bunu şunun içine koy ~/.zshrc:

sdo() sudo zsh -c "$functions[$1]" "$@"

Artık sdo" sudoyalnızca kullanıcı tanımlı işlevler için" olarak kullanabilirsiniz.

İşe sdoyaradığını onaylamak için : kullanıcı adınızı yazdıran kullanıcı tanımlı bir işlev üzerinde deneyebilirsiniz.

 birch@server ~/ 🍔 test() whoami

 birch@server ~/ 🍔 test
birch

 birch@server ~/ 🍔 sdo test
root

0

Bu benim için işe yarıyor gibi görünüyor:

function sudo (){
  args="$@"
  /run/wrappers/bin/sudo -u "$USER" zsh -i -c "$args"
}
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.