Online Book Reader

Home Category

Classic Shell Scripting - Arnold Robbins [169]

By Root 905 0
functions. User-defined functions in awk were described in Section 9.8. These two functions remove unneeded information from the uid and name arrays, respectively.

Running the program creates the files:

awk -f splitout.awk merge1

Managing UIDs

Now that we have separated the users by categories, the next task is to create a list of all the UID numbers in use:

awk -F: '{ print $3 }' merge1 | sort -n -u > unique-ids

We can verify that we have only the unique UID numbers by counting lines in merge1 and unique-ids:

$ wc -l merge1 unique-ids

20 merge1

14 unique-ids

34 total

Continuing through our task list, the next step is to write a program that produces unused UIDs. By default, the program reads a sorted list of in-use UID numbers and prints the first available UID number. However, since we'll be working with multiple users, we'll want it to generate a batch of unused UIDs. This is done with the -c option, which provides a count of UIDs to generate. Example 11-4 presents the newuids.sh script.

Example 11-4. The newuids.sh program

#! /bin/sh -

# newuids --- print one or more unused uids

#

# usage:

# newuids [-c N] list-of-ids-file

# -c N print N unused uids

count=1 # how many uids to print

# parse arguments, let sh issue diagnostics

# and exit if need be

while getopts "c:" opt

do

case $opt in

c) count=$OPTARG ;;

esac

done

shift $(($OPTIND - 1))

IDFILE=$1

awk -v count=$count '

BEGIN {

for (i = 1; getline id > 0; i++)

uidlist[i] = id

close(idlist)

totalids = i

for (i = 2; i <= totalids; i++) {

if (uidlist[i-1] != uidlist[i]) {

for (j = uidlist[i-1] + 1; j < uidlist[i]; j++) {

print j

if (--count = = 0)

exit

}

}

}

}' $IDFILE

Most of the work is done in the inline awk program. The first part reads the list of UID numbers into the uidlist array. The for loop goes through the array. When it finds two elements whose values are not adjacent, it steps through and prints the values in between those elements. It decrements count each time so that no more than count UID numbers are printed.

In shells that have arrays and that support arithmetic more directly, such as ksh93 and bash, it's possible to let the shell do all the work. In fact, this awk script was derived from a similar one for ksh93: see http://linux.oreillynet.com/pub/a/linux/2002/05/09/uid.html.

Creating User-Old UID-New UID Triples

We now have to process the dupusers and dupids files. The output file lists the username, old UID and new UID numbers, separated by whitespace, one record per line, for further processing. For dupusers, the processing is pretty straightforward: the first entry encountered will be the old UID, and the next one will be the new chosen UID. (In other words, we arbitrarily decide to use the second, larger UID for all of the user's files.) At the same time, we can generate the final /etc/passwd records for the users listed in both files.

* * *

Tip


This plan treats the disks of both systems equally, requiring that file ownerships (potentially) be changed on both systems. This is simpler to code, at the (possible) expense of more time spent changing file ownerships. A different option would be to leave the files on one system alone, making that system the "master" system, so to speak, and doing ownership changes only on the second system. This would be harder to code; we leave that as one of the infamous "exercises for the reader."

* * *

Here's the code:

rm -f old-new-list

old_ifs=$IFS

IFS=:

while read user passwd uid gid fullname homedir shell

do

if read user2 passwd2 uid2 gid2 fullname2 homedir2 shell2

then

if [ $user = $user2 ]

then

printf "%s\t%s\t%s\n" $user $uid $uid2 >> old-new-list

echo "$user:$passwd:$uid2:$gid:$fullname:$homedir:$shell"

else

echo $0: out of sync: $user and $user2 >&2

exit 1

fi

else

echo $0: no duplicate for $user >&2

exit 1

fi

done < dupusers > unique2

IFS=$old_ifs

We use the shell's read command to read pairs of lines from dupusers, sending the final password file entry to unique2. At the same

Return Main Page Previous Page Next Page

®Online Book Reader