Wie kann ich sudo-Befehle erhalten, um die Einstellungen in /root/.bashrc zu verwenden?


9

Ich habe .bashrcmit einer Reihe von Alias angepasst , speziell llundexport LS_OPTIONS='--color=auto'

Leider funktioniert dies nicht, wenn es mit verwendet wird sudo, daher habe ich auch Änderungen vorgenommen /root/.bashrc, aber dies scheint keinen Unterschied gemacht zu haben.

sudo envzeigt HOME=/rootundSHELL=/bin/bash

Wie kann ich sudoBefehle erhalten, um die Einstellungen in zu verwenden /root/.bashrc?

Ich verstehe, dass dies nur geschieht, wenn bashes interaktiv ausgeführt wird, und bin daher offen für weitere Vorschläge zur Anpassung.


@ daniel-gelling - Ich hatte immer das Gefühl, dass dieses Q ein XY-Problem ist - meta.stackexchange.com/questions/66377/what-is-the-xy-problem . Der Titel impliziert, dass sie etwas heraus wollen, /root/.bashrcaber wirklich, was das Q ist, sind die Aliase aus dieser Datei - dies ist nicht möglich - unix.stackexchange.com/questions/1496/… .
slm

@slm Was ich will, ist das Hinzufügen einer Methode zu bashrc - wie ich es in meiner persönlichen .bashrc-Datei sowie in der .bashrc-Datei für root getan habe, um die -rOption für crontab: zu "deaktivieren" crontab () { [[ $@ =~ -[iel]*r ]] && echo '"r" not allowed' || command crontab "$@" ;}. Dies funktioniert, wenn Sie als einer der Benutzer angemeldet sind. Wenn ich sudo crontab -res jedoch ausführe, wird es weiterhin ausgeführt.
Daniel Gelling

@ DanielGelling - sehen Sie, ob meine Antwort für Ihr Szenario funktioniert.
slm

Antworten:


6

sudoführt eine ausführbare Datei aus, keinen Shell-Befehl. Es weiß also nichts über Aliase. Wenn Sie ausgeführt werden sudo ls, wird sudo /bin/lskein lsAlias ​​verwendet, den Sie möglicherweise haben.

Sie können sudo lsden Alias ​​erweitern, indem Sie Folgendes in Ihr Feld einfügen .bashrc:

alias sudo='sudo '

Beachten Sie den nachgestellten Leerzeichen, der die Shell anweist, die Alias-Erweiterung mit dem folgenden Wort fortzusetzen sudo. Beachten Sie, dass das Erweitern von Aliasen nach sudo möglicherweise nicht immer eine gute Idee ist. Dies hängt davon ab, welche Arten von Aliasen Sie haben.

Darüber hinaus entfernt sudo die meisten Variablen aus der Umgebung. Dies wirkt sich nicht auf einen Alias ​​wie aus alias ls='ls $LS_OPTIONS', da dies eine Shell-Variable ist, die von der Shell verwendet wird, während der Befehl erweitert wird (und dessen Exportieren .bashrckeinen Zweck erfüllt). Dies würde sich jedoch auf Variablen auswirken, die vom Befehl verwendet werden, z LS_COLORS. Sie können sudo so konfigurieren, dass bestimmte Umgebungsvariablen beibehalten werden, indem Sie die Konfiguration bearbeiten: Führen visudoSie die Zeile aus und fügen Sie sie hinzu

Defaults env_keep += "LS_COLORS"

Mit diesen Einstellungen erhalten sudo llSie die Farben, die Sie gewohnt sind.

Alternativ können Sie eine Root-Shell mit ausführen sudo -s. Diese Shell lädt ihre Konfigurationsdatei ( ~/.bashrcfür Bash). Abhängig davon, wie sudo konfiguriert ist, bleibt dies möglicherweise HOMEin Ihrem Home-Verzeichnis oder ändert es in /root. Sie können erzwingen, dass das Home-Verzeichnis auf root mit gesetzt wird sudo -Hs. Um das ursprüngliche Home-Verzeichnis beizubehalten, führen Sie umgekehrt aus sudo env HOME="$HOME" bash.


3

Vielen Dank an diejenigen, die geantwortet haben und mich aufgefordert haben, man sudogenauer zu lesen .

sudo -s Wenn kein Befehl angegeben wird, wird eine interaktive Shell ausgeführt.

Diese interaktive Shell verwendet /root/.bashrcund enthält somit meine Anpassungen.

Der Befehl muss zwar separat eingegeben werden, dies ist jedoch in Ordnung.


2

Hintergrund

Ich hatte immer das Gefühl, dass diese Frage ein XY-Problem ist . Der Titel impliziert, dass sie etwas davon wollen, /root/.bashrcaber wirklich, was die Frage ist, sind die Aliase aus dieser Datei - dies wird allgemein als nicht möglich angesehen - Warum erkennt mein Bash-Skript keine Aliase? .

Grundsätzlich ist es beabsichtigt, dass Ihre Aliase nicht an sudound an anderen Orten erfasst werden, da sie nicht tragbar sind, und dies ist auch meine Meinung zu ihnen.

Alles, was sich in der Benutzerumgebung befindet, sollte nicht von Skripten und Software übernommen werden, die möglicherweise auf einer bestimmten Box ausgeführt wird. Mir ist jedoch klar, dass es Szenarien gibt, in denen möglicherweise Aliase in einem bestimmten Benutzerkonto vorhanden sind $HOME/.bashrc, die andere in interaktiven Szenarien nutzen möchten.

Zu diesem Zweck können Sie den Bash-Interpreter einfach anweisen, alle Aliase, die er während des Anmeldevorgangs findet, außerhalb des normalen Shell-Verhaltens zu erweitern, auf das Sie bei der Verwendung stoßen sudo.

Beispiel

Konfiguration

Zum Einrichten habe ich die folgenden Aliase, Umgebungsvariablen und Funktionen zu meinen Root-Benutzern /root/.bashrcund /root/.bash_profileDateien hinzugefügt .

$ grep smurf ~/.bashrc
alias brc_smurf='echo "ran alias from /root/.bashrc"'
export brc_smurf_env='var from /root/.bashrc'
bpf_smurf_func() { echo 'ran func from /root/.bash_profile'; }

$ grep smurf ~/.bash_profile
alias bpf_smurf='echo "ran alias from /root/.bash_profile"'
export bpf_smurf_env='var from /root/.bash_profile'
brc_smurf_func() { echo 'ran func from /root/.bashrc'; }

Ohne irgendetwas zu tun, keine dieser Arbeiten (keine Überraschungen):

$ sudo brc_smurf
sudo: brc_smurf: command not found

$ sudo bpf_smurf
sudo: bpf_smurf: command not found

Wir sehen, dass der aliasBefehl beim Ausführen keine Aliase anzeigt sudo:

$ sudo alias
$

Dieses Verhalten ist Ihr Hinweis darauf, dass Sie nicht erwarten sollten, dass auf Aliase zugegriffen werden kann. Aber wir machen weiter ...

Schritt 1 - Aliase sichtbar

Wenn wir rennen bash -ci, können wir Bash dazu bringen, zumindest Folgendes zu lesen $HOME/.bashrc:

$ sudo bash -ci 'alias' | grep smurf
alias brc_smurf='echo "ran alias from /root/.bashrc"'

Cool, also können wir es vielleicht laufen lassen?

$ sudo bash -ci 'alias; brc_smurf'
bash: alias; brc_smurf: No such file or directory

Schritt 2 - shopt -s expand_aliases

Nee. Auch dies ist beabsichtigt, wir tun etwas, was wir nicht tun sollen, also gibt es eine Reihe von "Sicherheitsvorkehrungen", die wir deaktivieren müssen. Die andere "Sicherheit" ist Bash.

$ sudo bash -ci 'shopt -s expand_aliases; alias; brc_smurf'
alias brc_smurf='echo "ran alias from /root/.bashrc"'
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
ran alias from /root/.bashrc

Hier sehen wir unsere Nachricht von /root/.bashrc, wir haben den Alias ​​des Root-Benutzers erfolgreich ausgeführt brc_smurf.

Schritt 3 - Was ist mit env vars?

Wenn Sie die oben gezeigte Methode verwenden, sollten diese jetzt auch funktionieren.

$ sudo bash -ci 'shopt -s expand_aliases; brc_smurf; echo $brc_smurf_env'
ran alias from /root/.bashrc
var from /root/.bashrc

Schritt 4 - was ist mit Funktionen?

Dies funktioniert auch wie erwartet:

$ sudo bash -ci 'shopt -s expand_aliases; brc_smurf; echo $brc_smurf_env;brc_smurf_func'
ran alias from /root/.bashrc
var from /root/.bashrc
ran func from /root/.bashrc

TLDR;

Sie können dies tun, um Zugriff auf Umgebungsvariablen + Aliase zu erhalten von /root/.bashrc:

$ sudo bash -ci 'shopt -s expand_aliases; <cmds>'

Nehmen Sie weg

Diese Methode aktiviert den Inhalt von /root/.bashrc, nimmt den Inhalt von nicht auf /root/.bash_profile.

Verweise


Ja, obwohl es einige kleine Unterschiede zwischen ihnen gibt, gehen wir hier nicht ins Detail ;-). Könnten Sie mir auf jeden Fall in der Situation helfen, die ich in den Kommentaren der Frage angegeben habe: Verwenden von Funktionen in .bashrcsudo; speziell die -rOption entfernen von crontab?
Daniel Gelling

Okay, aber das würde bedeuten, dass ich rennen müsste: sudo bash -ci 'alias; shopt -s expand_aliases; echo $brc_smurf_env'statt eines einfachen sudo echo $brc_smurf_env?
Daniel Gelling

Sie können das entfernen alias, das war nur, um sie zu zeigen, Sie müssten tunsudo bash -ci 'shopt -s expand_aliases; <cmds>'
slm

Das wäre eine Menge Tippen, nur um meine Crontab für root zu bearbeiten. Lassen Sie mich einen Alias ​​dafür erstellen :-P
Daniel Gelling

@ DanielGelling - yup, willkommen zu all dem Spaß unten in den Muscheldärmen.
slm

0

Es gibt eine Reihe von Einstellungen in der Datei / etc / sudoers, die speziell für die Ausführung von sudo-Befehlen oder zum Einrichten einer Umgebung für die Ausführung von sudo-Befehlen eingerichtet sind (z. B. Sicherstellen, dass der PATH nur vertrauenswürdige Speicherorte hat), je nachdem, was Sie davon erwarten Möglicherweise können Sie nicht das tun, wonach Sie suchen, wenn Sie tatsächliche Befehle in einer Shell ausführen müssen, um die Umgebung einzurichten. Sudoing bietet Ihnen keine Root-Login-Shell, sodass kein reguläres Profil für Sie erstellt wird.


0

Nehmen wir an, wir bearbeiten /root/.bashrc wie folgt:

$ sudo su -
Password: ******
# cat ~/.bashrc

echo "root bashrc file was read"
PATH=~/bin:$PATH
echo "$PATH"
export USERVAR=set
echo "$USERVAR"

umask 022
alias ll='ls $LS_OPTIONS -l'
alias l='ls $LS_OPTIONS -lA'

Lasst uns abmelden und wieder anmelden, damit bash die Datei liest:

# exit
$ sudo su -
root bashrc file was read
/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
set
root@here:~# alias l
alias l='ls $LS_OPTIONS -lA'
root@here:~# 

Wie Sie sehen können, wurde die Datei gelesen, der Pfad wurde geändert und die Aliase wurden festgelegt. Alles ist funktionsfähig, wie Sie es wünschen.

Sudo funktioniert jedoch immer noch nicht wie erwartet.

root@here:~# exit
$ sudo env | grep USERVAR              # no output 
$ sudo env | grep PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

PATH hat sich nicht geändert. Es kann Möglichkeiten geben, den Pfad in Sudoern zu ändern, aber ich empfehle Ihnen dringend, dies zu vermeiden. Außerdem werden Aliase, Funktionen und einige andere Änderungen immer noch nicht angewendet, wenn nur der Pfad geändert wird. Eine Datei muss bezogen werden. Wenn Sie dies für jedes Skript oder jeden Befehl tun, wird der Computer aufgefordert, mehr Arbeit ohne wirklichen Nutzen auszuführen. In Skripten werden keine Aliase verwendet (in Skripten gibt es keine praktische Verwendung).

Melden Sie sich einfach an, die .bashrcDatei wird automatisch geladen und macht sich an die Arbeit.

Sie können Bash wie folgt starten:

$ sudo bash
root bashrc file was read
/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
set
root@mail:/home/isaac/me/temp/clocks-master#

Aber wie Sie oben sehen, hat sich das pwd (das Arbeitsverzeichnis) nicht geändert, und wenn Sie etwas mehr untersuchen, haben sich auch einige andere Einstellungen nicht geändert. Deshalb lautet der richtige Befehl:

$ sudo su -

Wenn dieser Befehl zu lang ist, um ihn einzugeben, erstellen Sie einen Alias ​​oder eine Funktion im Benutzer (nicht root), in der dieser Befehl verwendet wird.

$ alias mysu='sudo su -'
$ mysu
# 

0

TL; DR: Sie können sudo -ieine definierte Funktion/root/.bashrc (aber keinen Alias) ausführen und haben auch Zugriff auf Variablen, die aus dieser Datei exportiert wurden:

sudo -i  Befehlsargumente

Aliase funktionieren dort zwar nicht, aber Sie können sie leicht in Funktionen konvertieren, wenn Sie sie zur Verfügung stellen möchten sudo -i.

Lesen Sie weiter für eine vollständige Analyse und weitere Details.


Hier gibt es einige Probleme, einige in der Funktionsweise von Sudo und einige in der Funktionsweise von Bash selbst ...

Standardmäßig sudowird nur nach Befehlen gesucht und die Shell umgangen, sodass das einfache Ausführen sudo llnur funktioniert, wenn sich llin einem der Verzeichnisse eine ausführbare Datei befindet $PATH. Um Aliase (oder Funktionen) verwenden zu können, müssen Sie sicherstellen, dass eine Shell als Teil des Prozesses aufgerufen wird.

Eine Möglichkeit wäre, so etwas wie sudo shoder auszuführen sudo bash, obwohl modern sudo(ich teste dies auf sudo 1.8.19p1) Optionen -sund -izu diesem Zweck hat.

Ein Versuch wäre also so etwas wie sudo -s ll(was gleichbedeutend ist mit der sudo bash -c 'll'Annahme, dass $SHELLes sich um Bash handelt, was aufgrund der von rcfileIhnen erwähnten der Fall zu sein scheint ). Aber das funktioniert auch nicht, da die Shell nicht interaktiv gestartet wird. Nicht-Anmeldemodus, der keine seiner Startdateien liest. Es ist im Wesentlichen dasselbe, als ob Sie ein Shell-Skript schreiben und #!/bin/bashes ausführen. Auf die Aliase (und Funktionen), die Sie in Ihrem ~/.bashrcSkript haben, kann von diesem Skript aus nicht zugegriffen werden ...

Als nächstes folgt die -iOption, mit der eine Anmeldeshell erstellt wird. Das ist mehr , viel versprechend, da es wird Ihre Startdateien lesen! Und doch wird sudo -i ll(äquivalent zu sudo bash -l -c 'll') immer noch nicht funktionieren. So , wie das möglich ist, da es hat die Definition des Lese llAlias?

Nun, die nächste Erklärung hier ist, dass bash standardmäßig keine Aliase erweitert, außer wenn die Shell interaktiv ist ... Diese von sudo -i(oder bash -l) gestartete Shell ist eine Login- Shell, aber immer noch nicht interaktiv.

Der nächste Schritt ist also, eine interaktive Shell zu erhalten, die dann funktioniert :

sudo bash -i -c 'll'

(Es ist natürlich auch in Ordnung, sowohl login als auch interaktiv zu seinbash -l -i -c ... .)

Eine andere Alternative besteht darin, weiterhin eine Anmelde- Shell (nicht interaktiv) zu verwenden, diese jedoch explizit zu bitten, Aliase zu erweitern. Dies funktioniert also auch:

sudo bash -l -O expand_aliases -c 'll'

(Der Fall, in dem bash interaktiv war, benötigte keine Login- Shell, da dies ausreicht, um die Initialisierungsdateien zu lesen, aber diese muss -lsie lesen.)

Dies sind ziemlich lange Befehlszeilen ... Und sie erfordern auch, dass Sie den gesamten Shell-Befehl zitieren. Wenn Sie also einen Alias ​​mit Argumenten aufrufen, müssen Sie all das in eine Zeichenfolge umwandeln ... Also ist es eine Art ungeschickt zu benutzen ...

Beachten Sie, dass ich früher über Aliase und Funktionen gesprochen habe ... Das war absichtlich so, da Funktionen hier tatsächlich viel praktischer sind. Sie benötigen nichts Besonderes (z. B. eine interaktive Shell oder das Festlegen einer bestimmten Option), um Funktionen auf einer Shell auszuführen, solange Sie deren Definition beziehen.

Wenn Sie also lleine Funktion anstelle eines Alias ​​definieren, können Sie diese direkt mit der -iVerknüpfung von sudo verwenden :

sudo -i ll

Und wenn Sie eine längere Befehlszeile mit Argumenten haben, können Sie diese auch hier direkt übergeben:

sudo -i ll -C -R /etc

(Vergleiche mit sudo bash -i -c 'll -C -R /etc'.)

Funktionen sind auch viel flexibler und in der Regel einfacher zu warten ... Es ist normalerweise einfach, einen Alias ​​in eine Funktion umzuwandeln. Die einzige Einschränkung besteht darin, immer dort zu verwenden, "$@"wo zusätzliche Argumente erwartet werden (normalerweise am Ende des.) alias.)

Zum Beispiel dieser Alias:

alias ll='ls $LS_OPTIONS -l'

Könnte in diese Funktion umgewandelt werden:

ll () {
    ls $LS_OPTIONS -l "$@"
}

Sie sind für die meisten Zwecke gleichwertig. Und wie bereits erwähnt, sollte die Funktion direkt von dort aus zugänglich sein sudo -i, sodass dies ein zusätzlicher Bonus ist.

Ich hoffe, Sie finden diese Antwort und Erklärung hilfreich!


DV - Ich habe nicht das Gefühl, dass dies die Situation mehr verbessert als das, was bereits hier ist.
slm

1
@slm glaube ich meine Antwort etwas hinzufügt, da keine vorherige Antwort die Form erwähnt der sudo -i command argumentsLage sein , laufen Funktionen aus /root/.bashrcverfügbar und haben exportierten Variablen. Aber ich sehe, dass meine Antwort vielleicht zu lang war und diese Informationen etwas vergraben waren ... Also habe ich eine TL; DR hinzugefügt, um sie zusammenzufassen (während die technischen Details der Untersuchung beibehalten wurden). Bitte werfen Sie einen weiteren Blick darauf.
Filbranden
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.