2013-06-05 18 views
7

Ich programmiere ein SH-Skript, das irgendwann die Shell des Benutzers in/bin/zsh ändern wird. Der Befehl ist natürlich wie folgt zusammen:Ermitteln der Shell des aktuellen Benutzers

chsh -s /bin/zsh 

jedoch fragt das für das Kennwort des Benutzers, und ich möchte nur, um sie auszuführen, wenn die Shell des aktuellen Benutzers nicht bereits /bin/zsh. Dazu brauche ich einen Befehl, der mir die aktuelle Shell mitteilen und mit "/bin/zsh" oder etwas Ähnlichem vergleichen würde. Ich habe gefunden, dass es eine c getusershell Funktion gibt, aber gibt es nicht eine Möglichkeit, dies aus einem Shell-Skript zu wissen?

Update: Entschuldigung, ich meine die Shell, die der Benutzer als seine bevorzugte Shell angegeben hat. Also ja, die in /etc/passwd angegebene. Die Logik dahinter ist, dass das Skript die bevorzugte Shell des Benutzers als zsh ändern soll, und ich möchte nur, dass das Skript zuerst prüft, ob es bereits zsh ist.

+2

grep/etc/passwd um die "offizielle" Shell des Benutzers zu erhalten. Beachten Sie jedoch, dass dieses Skript möglicherweise NICHT von dieser Shell ausgeführt wird. sie könnten sich sehr gut einloggen mit (sprich) demh, manuell bash ausführen und zu Korn shell, etc ... wechseln. –

+3

@MarcB Wenn wir nur Linux unterstützen, ist es besser, 'getent passwd" $ USER "' zu verwenden als grep '/ etc/passwd', da getent whahtever in nsswitch konfiguriert (LDAP, NIS, etc) sucht, während grepping'/etc/passwd' nur auf Systemen funktioniert, die für _use_ '/ etc/passwd' konfiguriert sind. –

+1

Was meinst du mit "aktuelle Shell"? Der aktuell in '/ etc/passwd' angegebene oder der aktuell ausgeführte? – Jens

Antwort

14

$SHELL gibt die Schale des aktuellen Benutzers:

$ echo $SHELL 
/bin/zsh 
+0

Ok, jetzt fühle ich mich albern, weil ich noch nie von $ SHELL gehört habe. Danke vielmals! – Ernesto

+2

Beachten Sie, dass $ SHELL nur mit dem in/etc/passwd identisch ist, wenn der Benutzer keine andere Shell gestartet oder ausgeführt hat. Der kugelsichere Weg, die Login-Shell zu finden, ist die Suche in '/ etc/passwd'. – Jens

+0

@Jens, nicht kugelsicher. Der Benutzereintrag könnte anderswo/etc/passwd wie NIS, NIS + oder LDAP sein. – jlliagre

2
$ awk -F: '$1 == "myusername" {print $NF}' /etc/passwd 
/bin/zsh 

Oder, wenn Sie den Benutzernamen in Shell-Variablen haben var:

awk -F: -v u=$var '$1 == u {print $NF}' /etc/passwd 

Dies setzt voraus, /etc/passwd lokal abgeschlossen ist (im Gegensatz zu sein NIS gedient, finden Sie in /etc/nsswitch.conf und entsprechende Manpage).

+0

Würde dies nicht nur die zugewiesene Shell des Benutzers erhalten? Die Frage fragt nach dem aktuellen. –

+0

Ich denke, "aktuelle Shell" bezieht sich auf die in '/ etc/passwd'. Es ist sinnlos, eine andere Shell mit 'chsh' in zsh zu ändern. Sie können eine laufende Shell nicht ersetzen. Aber ja, die Frage ist mehrdeutig. – Jens

+0

Ja, tut mir leid, meine Frage war nicht klar genug. Als ich "current shell" sagte, meinte ich die Shell, die der Benutzer momentan als seine bevorzugte zugewiesen hat, das heißt, diejenige, die ich gerade umstellen will, um zsh zu sein. – Ernesto

2

Der folgende Befehl Sie aktuelle Shell (in der CMD-Zelle) geben:

ps -p $$ 
+1

Dies ist die aktuell ausgeführte Shell, die die Login-Shell des Benutzers sein kann oder nicht. –

0

Die folgenden Werke:

ps p $$ | awk '{print $5}' 

Manchmal sind $ SHELL und Werte in/etc/passwd falsch.

+0

Dies ist die aktuell ausgeführte Shell, die die Login-Shell des Benutzers sein kann oder auch nicht. In welchem ​​Sinne wäre der Wert in "/ etc/passwd" "inkorrekt" (unter der Annahme, dass die Informationen tatsächlich aus der Datei "/ etc/passwd" stammen)? –

+0

Wenn Ihre Standard-Shell bash ist und Sie von bash tippen, geben Sie 'zsh' ein. Ihre aktuelle Shell ist nicht mehr die, die in '/ etc/passwd' angezeigt wird. – cforbish

+0

Das OP hat klar gemacht, dass die Shell-Spezifikation in '/ etc/passwd' (oder gleichwertig) ist, was er interessiert. –

4

Sie sollten nicht davon ausgehen, dass /etc/passwd der Speicherort der Shell des Benutzers ist.

Ich würde verwenden:

getent passwd $(id -un) | awk -F : '{print $NF}' 

Edit: Beachten Sie, dass getent nur auf Solaris implementiert ist, BSDs und GNU/Linux-basierte Betriebssysteme.

AIX, HP-UX und OS X haben ihre eigenen Möglichkeiten, um eine ähnliche Sache zu tun (resp. lsusers -c, pwget -n und dscl ...), so sollte dieser Befehl verbessert werden sollten diese OSes unterstützt werden müssen.

+0

Leider ist getent nicht POSIX, also nehmen Sie Solaris, BSDs oder Linux an. – Jens

+0

@Jens In der Tat, das ist eine Schande, dass POSIX diesen Befehl verpasst hat. – jlliagre

0
perl -e '@pw = getpwuid $< ; print $pw[8], "\n"' 

Dies setzt voraus, dass Perl installiert ist, richtig konfiguriert ist, und in Ihrem $PATH, die auf den meisten modernen Unix-ähnlichen Systemen eine ziemlich sichere Wette. (Es ist wahrscheinlich eine sicherere Wette als getent verfügbar ist, oder dass Benutzerinformationen tatsächlich in der /etc/passwd Datei gespeichert ist, oder dass der Wert von $SHELL wurde nicht verändert.)

$< ist die reale Benutzer-ID des aktuellen Prozesses .getpwuid() gibt ein Array mit Werten von /etc/passwdoder zurück, unabhängig von anderen Mechanismen, die das System verwendet (NIS, LDAP). Element 8 dieses Arrays ist die Login-Shell des Benutzers.

perl -e 'print((getpwuid $<)[8], "\n")' 

Die Gründe für die einstelligen + Betreiber oder die zusätzlichen Klammern sind eher obskure

perl -e 'print +(getpwuid $<)[8], "\n"' 

oder

:

Das Obige kann leicht verkürzt werden.

Verwandte Themen