Ich habe eine Funktion in meinem ~/.zshrc
:
findPort() {
lsof -t -i :$1
}
Der übliche Aufruf ist findPort 3306
.
Ich möchte es mit erhöhten Rechten ausführen. Aber ich bekomme "Befehl nicht gefunden".
➜ git 🍔 sudo findPort 3306
sudo: findPort: command not found
Ich nehme an, der Grund dafür ist, dass der Root-Benutzer entweder als nicht interaktive Shell ausgeführt wird (bezieht sich also nicht auf eine .zshrc-Datei) oder auf eine andere .zshrc
.
Ich habe ähnliche Fragen bezüglich alias
, aber keine Frage bezüglich benutzerdefinierter Funktionen gesehen. Die Antworten auf dieses Problem betreffen alias
das Hinzufügen eines Alias zu ~/.zshrc
:
alias sudo='nocorrect sudo '
Oder vielleicht:
alias sudo='sudo '
Ich habe beide Lösungen ausprobiert und das Problem besteht immer noch (ja, ich habe die Shell neu gestartet).
Ich habe auch versucht, auszuführen, sudo chsh
um sicherzustellen, dass meine Root-Shell unter läuft zsh
. Keine dieser Lösungen behebt das Problem "Befehl nicht gefunden".
Gibt es eine Möglichkeit, meine benutzerdefinierten Funktionen unter sudo auszuführen?
Antworten:
sudo
führt Befehle direkt aus, nicht über eine Shell, und selbst wenn eine Shell ausgeführt würde, um diesen Befehl auszuführen, wäre dies ein neuer Shell-Aufruf und kein Aufruf, der Ihren liest~/.zshrc
(selbst wenn eine interaktive Shell gestartet würde, würde er wahrscheinlichroot
s lesen~/.zshrc
, nicht Ihre, es sei denn, Sie haben konfiguriertsudo
, dass die$HOME
Variable nicht zurückgesetzt wird).Hier müssen Sie angeben, dass
sudo
eine neuezsh
Shell gestartet werden soll , und dies mitteilen,zsh
um Ihre zu lesen,~/.zshrc
bevor Sie diese Funktion ausführen:Oder:
Oder um Ihre aktuellen zsh-Funktionen mit den neuen Funktionen zu teilen, die
zsh
aufgerufen werden vonsudo
:Wenn Sie viele Funktionen definiert haben (z. B. bei Verwendung des Vervollständigungssystems), wird möglicherweise eine zu lange Argumentliste angezeigt . Sie können es also auf die
findPort
Funktion beschränken (und auf jede andere Funktion, auf die es sich stützt, falls vorhanden):Sie könnten auch tun:
Einbetten des
findPort
Funktionscodes in eine anonyme Funktion, an die Sie das Argument 3306 übergeben. Oder auch:(Das übergebene Inline-Skript
-c
ist der Hauptteil der Funktion).Sie könnten eine Hilfsfunktion verwenden wie:
Verwende nicht:
Da würden die Argumente von
sdo
eine andere Ebene der Shell-Analyse durchlaufen. Vergleichen Sie:quelle
sudo
. Ich konnte Ihre anonyme Funktionslösung anpassen , um genau das zu tun. Ich habe die folgende Funktion zu meiner hinzugefügt~/.zshrc
, die eine Funktion ist, um andere Funktionen mit erhöhten Berechtigungensdo() { sudo zsh -c "(){$functions[$1]} ${@:2}" }
Eine sehr einfache Lösung für mich war das Aufrufen einer interaktiven Shell mit
sudo -s
, die anscheinend auf meiner mit macOS gebündelten Version von zsh (5.2) funktioniert. Dies bietet mir die Funktionen von meinem~/.zshrc
.Aus der Sudo-Manpage, die dieses Verhalten nicht wirklich andeutet:
Ich bin mir nicht sicher, was Ihr Anwendungsfall ist, aber ich vermute, Sie suchen nach einer interaktiven Lösung.
quelle
myFunc
durch Eingabe zusudo myFunc
erhöhen - genauso wie ich jeden Prozess (wiesudo rm -rf .
) erhöhen würde . Diese Lösung erhöht meine gesamte Eingabeaufforderung und alle zukünftigen Funktionen und ändert meinen Benutzer für alle zukünftigen Funktionen - was ein bisschen übertrieben ist.sudo -s
Befehl startet eine weitere Instanz Ihrer Shell als Superuser. Wenn Sie diesen Befehl interaktiv ausführen, ist Ihre neue Shell interaktiv. Der Befehlsudo -s findPort 3306
führt den Befehl jedochfindPort 3306
in Ihrer Shell als Superuser aus und beendet ihn mit dem Statuscode dieses Befehls.Ich konnte eine wiederverwendbare Abkürzung für eine der in Stéphane Chazelas ' Antwort beschriebenen Lösungen erstellen . [Bearbeiten: Stéphane hat die von mir vorgeschlagene ursprüngliche Verknüpfung wiederholt. Der hier beschriebene Code ist eine neuere Version seiner Herstellung.]
Setzen Sie dies in Ihre
~/.zshrc
:Jetzt können Sie
sdo
als "nursudo
für benutzerdefinierte Funktionen" verwenden.Um zu bestätigen, dass dies
sdo
funktioniert: Sie können es mit einer benutzerdefinierten Funktion ausprobieren, die Ihren Benutzernamen druckt.quelle
Das scheint bei mir zu funktionieren:
quelle