Can we trigger a perl script in unix by sending a mail - perl

I want to know if we can trigger a perl script in unix through a sending a mail.
basically the script should check the incoming mail then trigger the perl script.
Also can some1 out on setting the mail access like reading and saving mail on my unix home.
-Thanks

There are two basic approaches you can take.
Configure your SMTP server to run incoming email through your script. Procmail is the usual tool for choice for this.
Poll (by using cron, or writing your script as a daemon) your IMAP/POP server/Maildir/Mbox/etc.
The former is usually the better option.

You can hack it like this:
inotifywait -m /var/mail/$USER | grep --line-buffered MODIFY | while read _unused_; do
#your perl script here
done
Explanation: It monitors /var/mail/$USER for changes & prints events on stdout. On every MODIFY event, it will trigger the script.
Note: This will work only for unix mails on localhost. Not on external server.
Known bugs:
A mail read activity will also trigger the script.

You can keep polling (unix) mail for any new mails.
while true; do
echo "\nq" | mail >/tmp/new_mail 2>&1 && /path/to/your/perl_script.pl arg1 arg2 ...
sleep 60
done
If you want, you can use contents of /tmp/new_mail in your perl program. If you don't need it, you can redirect mail output to /dev/null instead.

Related

Logrotate encryption before mailing

I use logrotate that sends me logs on a regular basis. My server is a VPS running Postfix as an outgoing-only SMTP server.
I would like all the mailed logs (which Logrotate sends) to be encrypted with PGP or S/MIME. How can I do that?
I searched for logrotate mail encryption, but couldn't find any. Therefore, I'm thinking that I can pass "nomail" command in logrotate config, but then add in the "postscript" a script to first encrypt the mail and then send.
So, is there a better way to encypt logrotate mail with PGP? Or that's what I need to do? I would appreciate any advise or an example of such a script.
Also, I'm not considering to use TLS as there are possible ways to bypass it in the SMTP server. And I would rather rely on encryption of individual messages.
Thanks!
Edit:
Here is my script I'm using for custom email sending(Without GPG for now):
#!/bin/bash
read MSG
echo $MSG | mail -s $1 $2
But when I force rotate with logrotate --mail=loggpg.sh --force /etc/logrotate.d/ufw I keep getting error about uncompression, do I need to manually uncompress it? Or there is smth wrong with the script?
Error I get:
error: mail command failed for /var/log/ufw.log.5.gz
error: uncompress command failed mailing /var/log/ufw.log.5.gz`
You can execute logrotate with --mail command line option. It will allow you to use your own shell/perl/python script to send email instead of default /bin/mail -s.
man logrotate
OPTIONS
...
-m, --mail
Tells logrotate which command to use when mailing logs. This command should accept two arguments: 1) the subject of the message, and
2) the recipient. The command must then read a message on standard input and mail it to the recipient. The default mail command is
/bin/mail -s.

Use mail command in terminal to send emails and specify From address

I have tried to send thousands of emails through running a csh script to execute the "mail" command. But all my emails were blocked by the recipient. I was told that the blocking reason is because of the workstation domain (kichisatoru#Sky.local), which is not a real domain (e.g. xx#gmail.com). How can I fix this issue, so the recipient can receive my emails in the standard way?
My csh:
#!/bin/csh
foreach eml (`ls *.eml`)
mail recipient#edu < $eml
echo $eml sent...
end
My problem is fixed! I have found a very detailed manual online http://www.developerfiles.com/how-to-send-emails-from-localhost-mac-os-x-el-capitan/

How to send stderr in email shell script (ash)

I wrote a shell script that I use under ash, and I redirect stderr and stdout to a log file. I would like that log file to be emailed to me only if stderr is not empty.
I tried:
exec >mylog.log 2>&1
# Perform various find commands
if [TEST_IF_STDERR_NOT_EMPTY]; then
/usr/bin/mail -s "mylog" email#mydomain.com < mylog.log
fi
My question is twofold:
1- I get a -sh: /usr/bin/mail: not found error. It seems that the mail command doesn't exist under ash (or at least under my linux box, which is a Synology NAS), what would be the alternative? Worst case, perl is available, but I would prefer to use standard sh commands.
2- How to I test that stderr is not empty?
Thanks
How to check if file is empty in bash
As for the first question, in your code you are calling mail but lower in the post you are calling email. Check your code and make sure it is mail.
Use which mail to get the full path. Maybe it is not installed in /usr/bin/.
Use find to locate mail.
If you can go to another shell, run it and then execute which mail to get the full path of mail in case the path is set up in the alternative shells.

Email an alert when sFTP connection cannot be reached?

I have a very small office environment, and my team sends created pdfs to an sFTP server daily.
Occasionally, I will get a call that someone can't log in to upload the files.
My normal course of action is to connect to the sFTP server myself, run a commmand like ls to determine it is responding.
I would like to be able to automate this with notification if there is a failure:
Login to the sFTP server (with credentials).
Run an LS command
Email if connection times out or login fails.
I have limited experience with writing Batch files, but I can't seem to figure a way to get only a 'failed' / no response to send an email.
Could anyone help with ideas? I'd like to run this as a VB or Batch in Scheduled Tasks, as I have a Server 2000 machine this could run on. I know batch has issue sending emails, but i have another batch file that uses Blat.exe to send an email with passed variables, so i could use that if i could get batch to send failed responses...
You should be able to do this with a batch file.
Create a file called logon.ftp. This file contains the FTP logon script. Mine contains:
open Ftp_server
ftpuser
ftppassword
ls -l
quit
The testftp.bat file:
ftp.exe < logon.ftp | grep "Not connected" > nul && call :alert_someone
#echo Logon successful
goto exit
:alert_someone
#echo %date% %time% > alert.txt
#echo ftp_server appears to not be taking logins. >> alert.txt
blat alert.txt -to you -from ftp_watcher -subject "alert %date% %time% ftp_server not taking logins"
:exit
You'll need to get blat, and grep so you can do the string checking. My winxp ftp doesnt support errorlevels, so I'm using the errorlevel returned from grepping the 'Not connected' string to figure out if this worked or not.
You can get wget or curl to do this as well, and they do support errorlevels.
Batch files can be a bit too basic for this kind of thing.
If you were able and willing to experiment with the Python programming language ( http://www.python.org ) and additionally install the Paramiko module ( http://www.lag.net/paramiko/ ) then it would be possible to write a script along the lines of...
import paramiko
try:
t = paramiko.Transport(('TheHostname', 22))
t.connect(username='MyUsername', password='MyPassword')
sftp = paramiko.SFTPClient.from_transport(t)
dirlist = sftp.listdir('.')
except:
print "It's Broken"
#Send e-mails and such here
that you could then schedule to run on a regular basis.

What's the difference between sendmail via CGI vs. Perl?

I am using sendmail in perl and noticed (after much banging of head against wall) that when the script is run at the command line it needs you to leave out the \n(s) after your e-mail and the recipient's email address in order to format the mail correctly, but when running via CGI if those \n(s) aren't there it returns an error stating that the recipient's e-mail is malformed.
Has anyone else encountered this? What are the two doing differently?
I am betting that you are getting data from prompts in on the commandline and not chomping them like this:
my $send_to = <>;
This means $send_to will already have a "\n". To make them both work the same way chomp the variables:
my $send_to = <>;
chomp($send_to);
or just
chomp(my $send_to = <>);
In a couple of your comments you mention that you're running the script from the command line with the -l option (perl -l foo.cgi).
The -l option enables automatic line-ending processing, and as your problem is with line endings, I suggest you try it without the -l.
Where is the data coming from? Hard coded in the script, or from a web form?
Just as an aside, if you get the recipient's email address from a web form, your form will be used by spammers. It's a 100% guarantee.
The term "CGI" is broad, if you mean your perl script run as a CGI versus yur perlscript run at the command line, I would look toward the pathing that the script has and its general inherited environment. Especially if your running it as different userids. If the webserver is in a chroot, etc.
use Data::Dumper;
warn(Dumper(\%ENV));
So I'm guessing that you have something like this for running it via the command line:
my $your_email = "you#foo.bar";
my $recipient_email = "them#foo.bar";
and this when "running via CGI":
my $your_email = "you#foo.bar\n";
my $recipient_email = "them#foo.bar\n";
So the question I would ask you then is how you're calling sendmail with the above variables, and also what you mean when you say "running via CGI" versus running via the command line? Are you just adding CGI code and still running via the command line or by visiting its URL in a web browser?