I am trying to make a simple email script so that other users can email me from the terminal.
The script is being made partly as a learning experience, and party because the other users are not very linux savvy, so I want them to easily be able to email from terminal, without having to learn the programs, and syntax.
I have ubuntu 16.04.1 Server
So far this is what I am working with:
clear echo -e "Please Enter Subject of email:\n " read subject echo -e "\n\nFrom: $USER\nTo: Adminstrator\nSubject: $subject\n\nEnter body of email: \n " read body echo -e "\nYour message is as follows:\n" echo -e "\nFrom: $USER\nTo: Administrator\nSubject: $subject\n\n" echo -e "$body \n\n" read -p "Send to Administrator (y/n)?" choice case "$choice" in y|Y ) echo "$body" | mail -s "$subject" ;; n|N ) echo "Roger Dodger. Email canceled";; * ) echo "invalid";; esac Things it can do:
request input for subject and body
send input to their respective variables.
call those variables, and send the email.
Things I want it to be able to do:
Allow pressing enter to go to a new line
Allow backspace
I have been everywhere twice, and I assume I am missing something, or lack some fundamental knowledge about how I can incorporate these features. I have tried using read with delimiters, cat with delimiters while loops (whatever that is) I have setup variable, aliases. I have read man pages I have tried piping it and substituting with $() I have tried sending the input to a file and calling that file.
Iam running out of ideas.
I could not get the terminal provide a a section to type in at all when using cat, but I could get it to provide the prompt with read.
I am thinking I want similar to
cat >> SEND && echo | ${BODY) and then where the script calls for it, just provide the ${BODY} variable.
In a terminal by itself, I successfully ran:
cat << SEND && echo | ${BODY} && echo "${BODY}" which allowed me to type multiple lines, until I typed SEND, and the pasted the ${BODY} variable whos output was correct.
Any ideas are apreciated.
71 Answer
I don't think what you're asking for is possible. When using read, you only have access to very minimal text editing abilities, it simply isn't designed for what you want it to do. Even if you can find a way to allow backspace and newlines, it is still a very cumbersome way of asking your users to provide input. It is very rarely a good idea to expect your users to type text directly into the running program. I suggest an alternative:
- Have your script read the subject from the command line.
- Have it read the body from an input file.
That way, your user doesn't need to type everything out manually, your script can be automated to send multiple emails, greatly increasing its usefulness and your users don't need to start everything again from scratch if they make a typo. Finally, they can format the email body as they want. So, for example, you can do something like this:
#!/bin/bash ## Parse command line options. while getopts ":s:f:" opt; do case $opt in s) subject="$OPTARG" ;; f) file="$OPTARG" ## Exit if the file isn't a file or isn't readble if [[ ! -r "$file" && ! -f "$file" ]]; then echo "File doesn't exist or isn't readble" exit fi ;; \?) echo "Invalid option: -$OPTARG" >&2;; esac done ## Read the email body body=$(cat "$file") ## Inform the user. The "\033[1m" starts bold formatting and the ## "\033[0m" ends it. Remove them if you don't want bold. echo -e "\033[1mYour message is as follows:\033[0m" cat<<EoF From: $USER To: Administrator Subject: $subject $body ------------------ EoF read -p "Send to Administrator (y/n)?" choice case "$choice" in y|Y ) echo "$body" | mail -s "$subject" ;; n|N ) echo "Roger Dodger. Email canceled";; * ) echo "invalid";; esac Then, you give it the subject and an input file. For example, if you have a file called message with the following contents:
$ cat message Dear John, I hope this email finds you well. I am writing to inquire about the price of the bridge you are selling. I would love to have a bridge like that in my garden since I think it would make my cows look larger. Looking forward to hearing from you, best, Jack. You would run the script like this:
$ foo.sh -s "about that bridge..." -f message Your message is as follows: From: terdon To: Administrator Subject: about that bridge... Dear John, I hope this email finds you well. I am writing to inquire about the price of the bridge you are selling. I would love to have a bridge like that in my garden since I think it would make my cows look larger. Looking forward to hearing from you, best, Jack. ------------------ Send to Administrator (y/n)? Alternatively, if you insist on having the users write the message on the fly, you could use the default editor available on your system:
#!/bin/bash clear echo -e "Please Enter Subject of email:\n " read subject ## create a temp file tmpfile=$(mktemp) cat<<EoF Press Enter to open an editor where you can write the body of the email. When finished, save and exit. EoF read ## Open the editor "$EDITOR" "$tmpfile" ## Read the body and delete the tmp file body=$(cat "$tmpfile") rm "$tmpfile" ## Inform the user. The "\033[1m" starts bold formatting and the ## "\033[0m" ends it. Remove them if you don't want bold. echo -e "\033[1mYour message is as follows:\033[0m" cat<<EoF From: $USER To: Administrator Subject: $subject $body EoF read -p "Send to Administrator (y/n)?" choice case "$choice" in y|Y ) echo "$body" | mail -s "$subject" ;; n|N ) echo "Roger Dodger. Email canceled";; * ) echo "invalid";; esac Finally, if you insist on making your life and that of your users more difficult than it needs to be, you can use cat > $tmpfile to write the body to the tmpfile, tell your users to hit Ctrl+D when they've finished writing:
#!/bin/bash clear echo -e "Please Enter Subject of email:\n " read subject ## create a temp file tmpfile=$(mktemp) ## Enter the body printf '\nPlease enter the body of the email below. Hit Ctrl+D when done.\n\n' cat > $tmpfile body=$(cat "$tmpfile") rm "$tmpfile" ## Inform the user. The "\033[1m" starts bold formatting and the ## "\033[0m" ends it. Remove them if you don't want bold. echo -e "\033[1mYour message is as follows:\033[0m" cat<<EoF From: $USER To: Administrator Subject: $subject $body EoF read -p "Send to Administrator (y/n)?" choice case "$choice" in y|Y ) echo "$body" | mail -s "$subject" ;; n|N ) echo "Roger Dodger. Email canceled";; * ) echo "invalid";; esac 8