Ernesto
Ernesto

Reputation: 4017

Determine the current user's shell

I'm programming a .sh script that will, at some point, change the shell of the user to /bin/zsh. The command is of course the following:

chsh -s /bin/zsh

However this asks for the user's password, and I would like to only execute it if the current user's shell is not already /bin/zsh. For this I need a command that would let me know the current shell, and compare it with "/bin/zsh" or something alike. I found there's a c getusershell function, but isn't there a way to know this from a shell script?

Update: Sorry, I mean the shell that the user has specified as his preferred shell. So yes, the one specified in /etc/passwd. The logic behind this is that, the script is about to change the user's preferred shell to be zsh, and I just want the script to check first if it isn't already zsh.

Upvotes: 16

Views: 24962

Answers (6)

jlliagre
jlliagre

Reputation: 30813

You shouldn't assume /etc/passwd is the location where the user's shell is stored.

I would use this:

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

Edit: Note that getent is only implemented on Solaris, BSDs and GNU/Linux based OSes.

AIX, HP-UX and OS X have their own ways to do a similar thing (resp. lsusers -c, pwget -n and dscl ...) so this command should be enhanced should these OSes need to be supported.

Upvotes: 7

Keith Thompson
Keith Thompson

Reputation: 263257

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

This assumes that Perl is installed, properly configured, and in your $PATH, which is a fairly safe bet on most modern Unix-like systems. (It's probably a safer bet than that getent is available, or that user information is actually stored in the /etc/passwd file, or that the value of $SHELL hasn't been changed.)

$< is the real UID of the current process. getpwuid() returns an array of values from /etc/passwd or whatever other mechanism the system uses (NIS, LDAP). Element 8 of that array is the user's login shell.

The above can be slightly shortened to:

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

or

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

The reasons for the unary + operator or the extra parentheses are rather obscure.

Upvotes: 0

Jens
Jens

Reputation: 72639

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

Or, if you have the username in shell variable var:

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

This assumes /etc/passwd is locally complete (as opposed to being NIS served; see your /etc/nsswitch.conf and respective man page).

Upvotes: 4

Daniel
Daniel

Reputation: 4173

$SHELL returns the shell of the current user:

$ echo $SHELL
/bin/zsh

Upvotes: 20

cforbish
cforbish

Reputation: 8819

The following works:

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

Sometimes $SHELL and values in /etc/passwd are incorrect.

Upvotes: 0

Ajitabh Mishra
Ajitabh Mishra

Reputation: 17

The following command will give you current shell (in the CMD cell):

ps -p $$

Upvotes: 0

Related Questions