0

I'm trying to add users to the system from a file. The file looks exactly like this:

user@domain.com password 1
user2@domain.com baddpassword 2

The numbers are their IDs. Its coming from a mysql db and I need to do something with those variables too so I need 4 variables. The USER, PASS, FIRSTID (being 1) and LASTID (being the last ID of the mysql dump in this case, 2. This is considering more than 2 entries at a time)

So far what I have is this:

for USER in `cat /root/users_w_pass | sed -n '1!p' | awk -F@ '{print $1}'`
do
    for PASS in `cat /root/users_w_pass | sed -n '1!p' | awk -F ' ' '{print $2}'`
    do
        useradd $USER -d /home/$USER -m -s /home/$USER.sh
        echo "$USER:$PASS" | chpasswd
    done
done`

When running this, the password does not get added to the corresponding user and I have no idea on how I am supposed to do that since I thought it would work but I can see how it doesn't. Also I need to do a lot more than just add them to the system, I am creating files and assigning ACLs for each, so running newusers on a file won't work here, especially that there is a third column as well.

unixpipe
  • 75
  • 1
  • 9
  • You should not use `cat` with programs that can read it directly, like `sed` and `awk`. You do not need to mix `sed` and `awk`, `awk` can do it all. You should not use old backtics, but parentheses instead `$(code)` so first line could be written. `for USER in $(awk -F@ 'NR>1 {print $1}' /root/users_w_pass)` – Jotne Apr 26 '14 at 06:33
  • Understood on that one. Still, I am having trouble with the core of my script. I can't seem to separate the variables in the for loop. I did read about using `while read` but unsure of its syntax in my case. Thanks. – unixpipe Apr 26 '14 at 06:35
  • Second loop could be `for PASS in $(awk 'NR>1 {print $2}' /root/users_w_pass)` – Jotne Apr 26 '14 at 06:36
  • I do not understand the logic you are trying to do. I would guess that one loop (for the username) should be enough. Then do what you need to do with one and one user. No need to loop the password. – Jotne Apr 26 '14 at 06:39
  • The dump from a mysql db is based on a status column of 0 for new users. So the dump comes in every hour or so, and about 20 or so users need to be added at once – unixpipe Apr 26 '14 at 06:40
  • So you have data in one format and need it in another? The input data is like the user in top of the post, but what is the expected output. (PS I do now nothing about Sql) – Jotne Apr 26 '14 at 06:42
  • You don't need to know much about SQL here :) Just that the dump looks exactly as above with the email password id, and I need to add the users to the system with the corresponding passwords next to it. I do see that looping the password destroys my script. How can I add the passwords properly? I can figure the rest of it out. The ID's are there for me to run a mysql command again and changing the status to 1 so that those users are now completed – unixpipe Apr 26 '14 at 06:46
  • 1
    You are using `-s /home/$USER.sh`. Are you really intending to define a different `SHELL` for each user? Do they exist? – R Sahu Apr 26 '14 at 06:47
  • Yes, as mentioned Im running alot of other commands below useradd. Their script is mutt. So when users log in, they are automatically launched into mutt. This is why I need to properly run the script. – unixpipe Apr 26 '14 at 06:49
  • Also, the title of the post does not reflect the problem you are trying to solve. It also has nothing to do with programming. Shouldn't you take it to http://superuser.com/? – R Sahu Apr 26 '14 at 06:50
  • I believe it does reflect my problem. It is a programming question in bash. What else is it? – unixpipe Apr 26 '14 at 06:51
  • Never use this syntax : `for i in $(command)` or for i in `command`. You could see this reminder : http://stackoverflow.com/questions/19606864/ffmpeg-in-a-bash-pipe/19607361#19607361 – Idriss Neumann Apr 26 '14 at 06:52
  • How can I use `while read` for both columns? The user being the first column, password being the second column. – unixpipe Apr 26 '14 at 07:03
  • @user3430013 : I've added an answer ;) – Idriss Neumann Apr 26 '14 at 09:26

1 Answers1

0

Using bash only :

while read email password trash; do
    user=${email%%@*}
    useradd "$user" -d "/home/$user" -m -s "/home/$user.sh"
    echo "$user:$password" | chpasswd
done < your_file.txt

Or (even if I prefer the first solution) :

while read; do
    set -- "$REPLY"
    user=${1%%@*}
    password=$2
    useradd "$user" -d "/home/$user" -m -s "/home/$user.sh"
    echo "$user:$password" | chpasswd
done < your_file.txt

If you want to filter the first line, here is a solution :

i=0
while read email password trash; do
    if [[ $i -ne 0 ]]; then
        user=${email%%@*}
        useradd "$user" -d "/home/$user" -m -s "/home/$user.sh"
        echo "$user:$password" | chpasswd
    fi
    (( i++ ))
done < your_file.txt

No need to use both awk and sed in this case and never use for i in $(command) : see this answer.

Community
  • 1
  • 1
Idriss Neumann
  • 3,760
  • 2
  • 23
  • 32