Welche Dateien werden bei Verwendung von su -c bezogen?


7

Kontext

Sie arbeiten an Ubuntu LTS 14.04. Sie sind als Root angemeldet. Sie führen den folgenden Befehl aus:

exec su simple_user -c "/bin/bash /etc/init.d/simple_user_service"

Damit wird der "simple_user_service" mit "simple_user" Berechtigungen und nicht mit Root-Berechtigungen gestartet.

Frage

Es scheint, dass "exec su simple_user -c" weder .bashrc noch .profile noch eine andere Datei mit normalen Quellen für ein neues interaktives Shell-Terminal enthält. Ich habe dies durch Hinzufügen dieser Zeile in der .bashrc-Datei simple_user bestätigt:

export TEST="Hello"

Dann in meinem Init-Skript "simple_user_service":

#!/bin/bash
### BEGIN INIT INFO
# Provides:             test_script
# X-Interactive:        true
# Short-Description:    Test script
### END INIT INFO

echo $TEST

Wenn ich das Skript ausführe, wird nichts gedruckt, aber wenn ich die folgenden Befehle ausführe:

su simple_user
echo $TEST
> Hello

Die TEST-Variable wird korrekt gesetzt und ausgedruckt.

Also habe ich mich gefragt: Gibt der Befehl "exec su simple_user -c" eine Datei "simple_user profile / bashrc" aus? Wenn ja, gibt es eine Möglichkeit zu wissen, welche?

Vielen dank für Deine Hilfe!

[Bearbeiten - 2 Stunden später]

Dank der Antwort, die ich erhielt, verstand ich die Anweisungen für "Man Bash" genauer. Ich habe das gefunden:

   When bash is started non-interactively, to run a shell script, for example, it looks for the variable BASH_ENV in the environment, expands its value if it  appears  there,  and
   uses the expanded value as the name of a file to read and execute.  Bash behaves as if the following command were executed:
          if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
   but the value of the PATH variable is not used to search for the file name.

Es ist wirklich interessant, da Sie BASH_ENV auf eine Datei setzen können, die jedes Mal, wenn Sie "su simple_user -c" verwenden, bestimmte Befehle ausführt, ohne die vollständige interaktive Logik laden zu müssen.

Vor der Ausführung su simple_user -ckönnen Sie also einfach Folgendes tun:

export BASH_ENV=~/.bash_script

Und legen Sie Dinge in Ihrer simple_user .bash_script-Datei fest, wie:

export TEST="Hello"

Wenn ich dann das Skript "simple_user_service" ausführe, wird "Hello" ordnungsgemäß gedruckt.

Es war wirklich nützlich für mich, da ich dies brauchte, um die gesamte "rvm" -Umgebung (Ruby) zu laden und ein bestimmtes Skript auszuführen.

Möchten Sie mehr wissen?

Warum all diese Schwierigkeiten?

Weil ich Ruby God installiert habe: http://godrb.com/, um dieses spezielle Skript zu überwachen (ein verzögertes Job-Skript).

Und ich benutze "rvm", um verschiedene Rubine zu verwalten.

Und das Skript löscht bei Bedarf automatisch Berechtigungen, indem es ausgeführt wird exec su application_user -c "/bin/bash application_script"

Da Gott mit Root-Rechten ausgeführt werden muss und rvm nur in .bashrc / .profile-Dateien geladen wird, brauchte ich eine Möglichkeit, die rvm-Umgebung in meinem Skript ordnungsgemäß zu laden. Ich könnte einfach den Befehl rvm load in das Skript einfügen, aber dann wäre mein Skript von der Umgebung abhängig gewesen, und das war nicht akzeptabel.

Also habe ich dies in mein Skript eingefügt, bevor Berechtigungen gelöscht werden:

if [ -e "config/BASH_ENV" ]; then
  export BASH_ENV=$(cat config/BASH_ENV)
fi

Dank dessen kann ich rvm in die Datei laden, die ich in der Datei config / BASH_ENV festgelegt habe. Zum Beispiel könnte es sein:

# In config/BASH_ENV file of your rails app:
export BASH_ENV="~/.bash_script"

# In /home/simple_user/.bash_script 
[[ -s "/etc/profile.d/rvm.sh" ]] && . "/etc/profile.d/rvm.sh" # Load RVM function

Dann arbeiten mein Drehbuch und Gott wie erwartet.

Ich habe all diese Dinge nicht erklärt, bevor ich Antworten bekam, damit sich die Leser auf die eigentliche Frage konzentrieren konnten.

Aber als ich eine gute Antwort bekam und dank dieser eine gute Lösung fand, schrieb ich diese Bearbeitung, damit sie für andere nützlich sein kann.

Danke noch einmal!

Antworten:


10

Wenn Sie das tun:

su some_user -c 'some_command'    

Das some_commandwird ausgeführt als:

bash -c 'some_command'

Unter der Annahme , bashist some_user‚shell definiert /etc/passwd.

Wenn Sie dies tun bash -c 'some_command', erzeugen Sie im Grunde genommen eine nicht interaktive (und natürlich nicht angemeldete ) Sitzung von bash. Da im nicht interaktiven Modus keine Datei von der Shell bezogen wird, wird erwartungsgemäß keine Datei gelesen.

Beachten Sie, dass ~/.profiledie Daten in einer interaktiven Anmeldesitzung von bashund ~/.bashrcin einer interaktiven Sitzung ohne Anmeldung von bezogen werden bash. Beachten Sie auch, dass Ubuntu Quellen ~/.bashrcaus ~/.profile.

Weitere Informationen finden Sie im INVOCATIONAbschnitt von man bash.

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.