Finding out the default shell of a user within a shell script
Solution 1
$ finger $USER|grep -oP 'Shell: \K.*'
/bin/mksh
Solution 2
The environment variable, SHELL
would always expands to the default login shell of the invoking user (gets the value from /etc/passwd
).
For any other given user, you need to do some processing with /etc/passwd
, here is a simple awk
snippet:
awk -F: -v user="foobar" '$1 == user {print $NF}' /etc/passwd
Replace foobar
with the actual username.
If you have ldap
(or something similar in place), use getent
to get the database instead of directly parsing /etc/passwd
:
getent passwd | awk -F: -v user="foobar" '$1 == user {print $NF}'
or cleanest approach, let getent
do the parsing (thanks to @Kusalananda):
getent passwd foobar | awk -F: '{print $NF}'
Solution 3
Since getent
isn't a standard command on MacOS, you may wish to use a lower level getpwuid
call that will consult the naming services the machine is configured for. This may require calling out to perl
or python
, which are pretty common across most Unix-like platforms
eg this will return the shell for the current user:
perl -e '@x=getpwuid($<); print $x[8]'
Solution 4
Maybe this:
grep ^$USER: /etc/passwd | cut -f 7 -d :
Solution 5
You can get the user's default shell from the environment like this:
echo $SHELL
But not like this:
echo $0
The latter will just tell you what shell your script is currently using. So you want the first option above.
Related videos on Youtube
Spaniard89
Updated on September 18, 2022Comments
-
Spaniard89 almost 2 years
I was wondering if there's a way to find out the default shell of the current user within a shell script?
Use case: I am working on a script that sets an alias for a command and this alias is set within a shell script.
!# /bin/bash alias = 'some command to set the alias'
There's a logic in the script where it tries to find the default shell of the user that executes the script and adds this alias in the respective ~/.bashrc or ~/.zshrc file
But as I am adding a shebang in the front of the script and explicitly asking it to use bash, answers posted here always return bash as expected although I am executing this script on a ZSH terminal.
Is there a way to get the shell type where the script is executed regardless of the shebang set?
I am looking for a solution that works on both Mac and all the linux based bistro.
-
Spaniard89 over 7 years@StephenRauch I should have mentioned it earlier, I am looking for a method that works on both Mac and Linux based system. /etc/passwd on Mac does not contain the user information and its only consulted in a single user mode.
-
terdon over 7 yearsWhat does
/etc/passwd
have on OSX? I had a quick look online and it appears that the shell is there, just not the username. The user ID's still there though, why don't you use that? -
jamesqf over 7 yearsI'd wonder if it's even possible to have an exhaustive list of shells. Or do all shell startup files always conform to .{name_of_shell}rc?
-
Sergey Ponomarev over 3 yearsHere is an answer to OSX stackoverflow.com/a/16375660/1049542
-
-
Spaniard89 over 7 yearsThanks for the answer. I should have mentioned it earlier, I am looking for a method that works on both Mac and Linux based system. /etc/passwd on Mac does not contain the user information and its only consulted in a single user mode.
-
Spaniard89 over 7 yearsThanks it works like a charm! This is the only solution that probably works for both mac and linux based bistro.
-
Spaniard89 over 7 yearsBTW, I edited the command a little bit to make it agnostic to all OS
finger $USER | grep 'Shell:*' | cut -f3 -d ":"
as the grep options -P is not supported on Mac. -
Stephen Harris over 7 yearsNote that
finger
may not be installed on all machines. It's an optional package on RedHat based systems. -
Ipor Sircer over 7 years@Kishorepandey: you can use
getent|grep ^$USER:|cut -f: -f7
instead of finger, if finger was not installed by default. -
Gilles 'SO- stop being evil' over 7 years@Kishorepandey Don't do this. Use the
SHELL
environment variable if it's present. Looking at the user database will give you a result (the user's login shell) but it might not be the right result (the user's favorite interactive shell) — it depends on the user's configuration. -
Kusalananda about 7 yearsThis does not improve on any of the already given answers.
-
smac89 almost 6 years
finger $USER | pcregrep --color -io1 'shell:\s*(.+)'
-
Gabriel Staples about 4 yearsFor an explanation of that
awk
command, see here: unix.stackexchange.com/a/589221/114401 -
Rich almost 4 yearsUse
getent
unless you're never ever going to use a directory for authentication ever. If Unix doesn't havegetent
you need to restate your question to find the equivalent in your particular Unix distro. -
Rich almost 4 years
$SHELL
is not guaranteed to be the user's default shell either. You wantgetent
or its macOS equivalent. -
Konrad Rudolph over 2 yearsAlas the
SHELL
environment variable doesn’t always exist! In fact, even when the parameter exists in a shell, it might not be exported. And usinggetent
(orfinger
) works well on Linux but fails on some other systems. I’m not aware of a foolproof, maximally portable way. As a fallback I’d just iterate a few common shell path locations and, if those don’t exist, call it a day. -
Konrad Rudolph over 2 yearsIn general you should not inspect
/etc/passwd
manually, it isn’t guaranteed to be synchronised with the user database if directory services (e.g. LDAP) are used. Whereasgetent
will continue to work (if it is installed). -
Stéphane Chazelas over 2 yearsThat only works on systems where the user db is stored in /etc/passwd, as opposed to LDAP, NIS+, SQL... That also could give you the wrong result if
$USER
contains regex operators (such as.
which is common in usernames). There's no guarantee$USER
will contain the current user name.$LOGNAME
(from processes that are part of a login session) is standard, so are$(logname)
,$(id -un)
(though the latter only gives one user with the current process uid as uid, which may not be the same user as the one who logged in in cases where several users share the same uid) -
Admin about 2 yearsResponding to Gilles's comment: $SHELL is the user's login shell. My login shell is fish: if I unset the SHELL variable and then launch bash, SHELL is "/path/to/fish"