3
\$\begingroup\$

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" <<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
asked Oct 21, 2017 at 10:23
\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

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" <<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".

answered Oct 29, 2017 at 6:33
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.