Generate E-Mails with content on different files

Hello,

I am using a script to create a random password for a user.
The file looks like

 
user1:thepassword1  
user2:thepassword2  
user3:thepassword3   

Passwords are openssl passwd hashed. I have an own file where the password is written in cleartext.
Now i want to send an E-Mail to the users with the new password.
I have a file (maillist.txt) with

 
user1:mail@domain1.tld  
user2:mail@domain2.tld  
user3:mail@domain3.tld   

Now i want to generate an E-Mail to user1.
This should generate an E-Mail to mail@domain1.tld, containing the username (user1) and the password (password1). Automatic for each user.
I want to do it with mailx.
Can you please help me?
Regards
Manu

Hashing is not reversible, the hash file is useless for anything but verifying a password someone gives to you.

while IFS=":" read USERID EMAIL
do
        PASS="$(awk -F: '$1 == USERID { print $2 }')
        if [ -z "$PASS" ]
        then
                echo "No pass for user $USERID" >&2
                continue
        fi

        mailx -s "password for $USERID" EMAIL <<EOF
From:  someone@myemailserver
Subject:  Automatic password
Your automatically generated password is $PASS
EOF

        [ "$?" -eq 0 ] || echo "Couldn't email password for $USERID" >&2
done < emailfile

Test this with example data before you try it for real.

Thank you.
I' am using this Script right now...

join -t: cleartext.txt maillist.txt | awk -F: '{ print "echo Username: "$1" Passwd: "$2" | mailx -s Information "$3 }' |sh

$1 is the Username from Cleartext.txt
$2 is the Password from Cleartext.txt
$3 is the email from the user in maillist.txt
This works fine like this, but i want to add more text (Something like "Hello, your password has been..."). But if i do this, i get an error: i get an unexpected error.
Script from above changed to... { print "echo Blablabla \n test Username: ...}

An awk script which generates shell commands is probably not the greatest idea, it would be a security and quoting nightmare. It's not the use of awk or sh, as much as the way they're joined, that's the problem. What if someone's password happens to be '" ; sleep 900000 ? That would be fun. Handle the reading yourself, so that there's no opportunity for arbitrary execution.

I'd forgotten about join, though, that simplifies my script a lot:

join -t: cleartext.txt maillist.txt | while IFS=":" read -r USERID PASS EMAIL
do
        mailx -s "password for $USERID" EMAIL <<EOF
From:  someone@myemailserver
Subject:  Automatic password
Your automatically generated password is $PASS
This email can contain as many lines as you want
etc
etc
EOF
done

Hey, thats perfect! Thanks.
Is there just a possibilty to set to "TO" E-Mail to the Adress from the maillist.txt?
Currently all Mails are send to correct recipient, but the "TO" Field is "EMAIL@hostname"@domain.tld.
And where do you define the Variables? (Like $PASS, $USERID etc?)

I edited the Script by adding a -r, to show an sender mail.

join -t: cleartext.txt maillist.txt | while IFS=":" read -r USERID PASS EMAIL
do
        mailx -r "donotreply@domain.tld" -s "password for $USERID" EMAIL <<EOF
Hello $USERID,

Your automatically generated password is $PASS
EOF
done

read defines them, setting them for every line read. It takes the variable NAME, not the variable itself, which is why its read -r VARNAME and not read -r $VARNAME

Try putting it in with the email, like:

mailx -s "password for $USERID" EMAIL <<EOF
To:  $EMAIL
From:  someone@myemailserver
Subject:  Automatic password

Your automatically generated password is $PASS
This email can contain as many lines as you want
etc
etc
EOF

p.s. Do not indent the email contents to make them look prettier in the script, it won't work right if you indent it, especially the ending EOF. That has to be at the literal beginning of the line to properly end the here-document.

Actually not.
The Mail is still from "EMAIL@hostname"@domain.tld
The E-Mail just looks like:

To:  test@manuh.xyz 
From: someone@myemailserver   
Subject:  Automatic password    
Your automatically generated password is test   
This email can contain as many lines as you want  
etc   
etc

Normally i use mailx like that.
mailx -r sender@domain.tld -s "Mail Subject" recepient@domain.tld

I found another way..
How would this be (security`?)

#!/bin/bash
>tmp.txt
join -t: cleartext.txt maillist.txt | while read line
do
  echo $line
  USER=$(echo $line | awk -F: '{ print $1 }')
  PSWD=$(echo $line | awk -F: '{ print $2 }')
  EMAILID=$(echo $line | awk -F: '{ print $3 }')
  echo "Hello $(echo $USER | tr a-z A-Z), your password has been changed!!!<br>" >tmp.txt
  echo "<b>Username</b>: $USER<br>" >>tmp.txt
  echo "<b>Password</b>: $PSWD<br>" >> tmp.txt
  cat tmp.txt | mailx -s "$(echo -e 'Password Changed!!!\nContent-Type: text/html')" $EMAILID
done

USER is a special variable and should not have its value changed. Try something else, like USERID.

I think an HTML email is a bad idea as any < > & in passwords are liable to be eaten. You can work around that but it would be a lot of processing. (That's also the reason for read -r, incidentally - to prevent backslashes from being eaten.)

You don't need echo to put two lines into a variable. Just put a real newline inside the "" and it will contain a real newline, like

"Hello
World"

but again I don't think an HTML email is a good idea unless you want to get really fancy.

Most of that can be stripped down back into what I just gave you -- there's no need for all those awk's.

If your mailx supports -r, you can set the From: address. If it doesn't support -r, you can try mailx -a "From: Foo Bar <foo.bar@someplace.com>" ...

Otherwise, you may be out of luck.

join -t: cleartext.txt maillist.txt | while IFS=":" read -r USERID PSWD EMAILID
do
  echo $line
  mailx -r "my@email.com" -s "Password Changed!"  $EMAILID <<EOF
Hello $(echo $USERID | tr 'a-z' 'A-Z'), your password has been changed!
Username: $USERID
Password: $PSWD
EOF
done

Okay thank you a lot.
I will use your last Code - thats perfect! :smiley: