One more way to solve the above problem of finding your default shell, just for fun:
grep ^$USER: /etc/passwd | grep -Eo ':([^:]*)$' | tr -d ':'
Brief description: find the line with the user, find the :/my/shell
path at the end, delete the :
char from it.
Now, let me expand on @heemayl's answer, and explain the magical awk
code he uses.
1. Just remember the simple stuff:
First off, this:
awk -F: -v user="foobar" '$1 == user {print $NF}' /etc/passwd
while being 100% correct, and the most "right" answer perhaps, is impossible to remember--you'd have to learn awk
and then rewrite it logically from scratch each time. What is easy to remember, however, is this: the default shell for a user is the last field on the user's line in the "/etc/passwd" file, where fields are separated by the colon :
symbol, and each line in that file begins with a username.
Now, with that knowledge, just think: "ok, I need to find my username line in /etc/passwd". So, do this:
grep $USER /etc/passwd
OR (same effect)
cat /etc/passwd | grep $USER
You'll get something like this:
my_username:x:1001:1001::/home/my_username:/bin/bash
Cool! My default shell is therefore the last field, which means whatever is after the last :
symbol. It is /bin/bash
. Done.
2. Explanation of this awk
command:
awk -F: -v user="foobar" '$1 == user {print $NF}' /etc/passwd
awk
is a pattern matching language. You can read the GNU awk, or gawk
, manual here, which is a great reference: https://www.gnu.org/software/gawk/manual/gawk.html
/etc/passwd
at the end is the file to open and process with awk
-F:
says to change the "'F'ield separator" from space (the default) to :
.
- The
-v
option sets an awk 'v'ariable you are naming user
here, to "foobar"
- Now the actual
awk
program is stored between the single quotes. It's simply $1 == user {print $NF}
. Remember: it is its own programming language! It is based on a pattern match or boolean check { action } type flow. It scans down the file one "record" (or line, by default) at a time. $1
is the first field in any given line, and remember, we told it that fields are separated by :
, so the first field is my_username
. So, $1 == user
says "does the first field equal the value stored in the awk variable user
"? If so, do the action specified in curly braces { }
. The action is to print the value of $NF
, where the internal NF
variable contains the 'N'umber of 'F'ields for this line. So, the number of fields is 7, since ::
contains 1 empty field between those two colons. Therefore, $NF
is actually $7
, or the value of the 7th field, which is /bin/bash
for this user. Behold, the magic of the pattern-matching language, awk
.
- Done.
3. How to configure a default shell for your user:
What if you want to set or change the default shell for a given user? Use chsh
. man chsh
says it is used to "change login shell". Here's how to use it:
sudo chsh my_username --shell /path/to/my/shell
Ex: set to use the bash
shell (my preferred choice) by default:
sudo chsh my_username --shell /bin/bash
Additional awk
learning resources:
- See some hello world and syntax test files for
awk
I wrote here: https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/tree/master/awk
- Study
git diffn
, as an example, here. Note: git diffn
is a wrapper I wrote around git diff
, to show line numbers.
/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? – terdon Mar 18 '17 at 16:03