Assignment 9
- Write a script called read1 that will ask the user to enter a username,
then display information about that user.
Display the username, UID, and home directory. Hint: /etc/passwd
contains the username (field 1), UID (field 3), home directory (field 6).
Solution:
# list user info echo -n "Enter a username: " read user junk uid=$(grep $user /etc/passwd | cut -d: -f3) home=$(grep $user /etc/passwd | cut -d: -f6) echo "$user $uid $home"
- Write a script called read2 that will display information about each user on the system.
Display one line per user containing: the username, UID, and home directory.
Solution:
This could be done with a one liner, like this:cat /etc/passwd | cut -d: -f1,3,6
But in preperation for number 3 it would be better to do it like this:
# list user info while read line do user=$(echo $line | cut -d: -f1) uid=$(echo $line | cut -d: -f3) home=$(echo $line | cut -d: -f6) echo -e "$user\t$uid\t$home" done < /etc/passwdNote that stdin is redirected from /etc/passwd on the done line. This can also be done by piping:
cat /etc/passwd | while read line do ... done
- Write a script called read3 the same as above but will add the name of each of the users groups.
Hint 1: /etc/group file contains group name (field 1) and names of users that belong to that group (field 4).
A user can belong to more than one group.
Hint 2: Loop on the lines of /etc/passwd and inside the loop look for groups for each user.
Solution:
# list user info while read line do #echo $line user=$(echo $line | cut -d: -f1) uid=$(echo $line | cut -d: -f3) home=$(echo $line | cut -d: -f6) echo -ne "$user\t$uid\t$home\t" echo $(grep $user /etc/group | cut -d: -f1) done < /etc/passwd - Change the last script (call it read4) to format the output so that each column has enough width,
the UID is right justified, and the other fields are left justified.
Solution:
Here we do it the hard way. A for loop goes through the groups and concatinates them to the variable groups# list user info while read line do #echo $line user=$(echo $line | cut -d: -f1) uid=$(echo $line | cut -d: -f3) home=$(echo $line | cut -d: -f6) groups= for group in $(grep $user /etc/group | cut -d: -f1) do groups="$groups $group" done printf "%-10s%6d %-20s%s\n" "$user" "$uid" "$home" "$groups" done < /etc/passwdOR tr will get rid of those linefeeds and replace them with spaces:
# list user info while read line do #echo $line user=$(echo $line | cut -d: -f1) uid=$(echo $line | cut -d: -f3) home=$(echo $line | cut -d: -f6) groups=$(grep $user /etc/group | cut -d: -f1 | tr '\12' ' ' ) printf "%-10s%6d %-20s%s\n" "$user" "$uid" "$home" "$groups" done < /etc/passwdOR echo will take a list of arguments and output them with a single space between each. This is also a nice exaple of nested command substitutions.
# list user info while read line do #echo $line user=$(echo $line | cut -d: -f1) uid=$(echo $line | cut -d: -f3) home=$(echo $line | cut -d: -f6) groups=$(echo $(grep $user /etc/group | cut -d: -f1) ) printf "%-10s%6d %-20s%s\n" "$user" "$uid" "$home" "$groups" done < /etc/passwdOR why not just use echo to output the groups? It worked in question 3 and nobody said we have to use printf.
# list user info while read line do #echo $line user=$(echo $line | cut -d: -f1) uid=$(echo $line | cut -d: -f3) home=$(echo $line | cut -d: -f6) printf "%-10s%6d %-20s" "$user" "$uid" "$home" echo $(grep $user /etc/group | cut -d: -f1) done < /etc/passwd