Shell script for reading /etc/passwd into SQLite I want to read 4 columns, namely UID, GID, username and home directory of specific users from /etc/passwd into an SQLite database. I found this to create many subprocesses, and I'd like to have some improvement suggestions.

#!/bin/sh
db="$PWD/users.db"
users=$(grep -E 'joe|bill|tom' /etc/passwd)
sqlite3 "$db" &lt;&lt;EOF
DROP TABLE Users;
CREATE TABLE Users \
    (UID INTEGER PRIMARY KEY, GID INTEGER, Username TEXT, Home TEXT);
EOF
echo "$users" | while IFS= read -r line
do
    sqlite3 "$db" \
        "INSERT INTO Users VALUES ( \
         $(echo "$line" | cut -d":" -f3),   \
         $(echo "$line" | cut -d":" -f4),   \
        '$(echo "$line" | cut -d":" -f1)',  \
        '$(echo "$line" | cut -d":" -f6)');"
done
Just don't create that many subprocesses. Your objective is to prepare a string of INSERT statements and feed it to one invocation of sqlite3. So drop the whole while read block and do the required text manipulations on the queried passwd entries before passing them off to sqlite3:

#!/bin/sh
db='./users.db'
sqlite3 "$db" &lt;&lt;EOF
DROP TABLE Users;
CREATE TABLE Users \
    (UID INTEGER PRIMARY KEY, GID INTEGER, Username TEXT, Home TEXT);
$(getent passwd 'joe' 'bill' 'tom' | awk -F':' -v quote="'" -v OFS="', '" \
    '{print "INSERT INTO Users VALUES ("quote $3, $4, $1, $6 quote");"}')
EOF


Doing a grep on /etc/passwd has a few drawbacks: the passwd file might not be located in /etc (I don't know of any Unix-like OS for which this is true, though), and it won't have the users that are stored in LDAP/NIS, etc. On the other hand, some systems don't have getent, so this method is not perfect, either. You might want to fall back to grep if getent returns a "command not found".