I am using autopostgresqlbackup to backup my PostgreSQL database on Debian 8.3. Everything works except the zipped backup does not get emailed to me. When I run the script with "sudo autopostgresqlbackup" I get:
Can't stat <redacted name>#gmail.com: No such file or directory
<redacted name>#gmail.com: unable to attach file.
From my research this may be caused by mutt requiring "the -a option must be placed at the end of command line options"
The relevant part of the script itself seems to be:
ATTSIZE=`du -c $BACKUPFILES | grep "[[:digit:][:space:]]total$" |sed s/\s*total//`
if [ $MAXATTSIZE -ge $ATTSIZE ]
then
if which biabam >/dev/null 2>&1
then
BACKUPFILES=$(echo $BACKUPFILES | sed -r -e 's#\s+#,#g')
biabam -s "PostgreSQL Backup Log and SQL Files for $HOST - $DATE" $BACKUPFILES $MAILADDR < $LOGFILE
elif which heirloom-mailx >/dev/null 2>&1
then
BACKUPFILES=$(echo $BACKUPFILES | sed -e 's# # -a #g')
heirloom-mailx -s "PostgreSQL Backup Log and SQL Files for $HOST - $DATE" $BACKUPFILES $MAILADDR < $LOGFILE
elif which mutt >/dev/null 2>&1
then
BACKUPFILES=$(echo $BACKUPFILES | sed -e 's# # -a #g')
mutt -s "PostgreSQL Backup Log and SQL Files for $HOST - $DATE" $BACKUPFILES $MAILADDR < $LOGFILE
else
cat "$LOGFILE" | mail -s "WARNING! - Enable to send PostgreSQL Backup dumps, no suitable mail client found on $HOST - $DATE" $MAILADDR
fi
else
cat "$LOGFILE" | mail -s "WARNING! - PostgreSQL Backup exceeds set maximum attachment size on $HOST - $DATE" $MAILADDR
I have tried to reverse the order of "-a #g" in the above code, but then I get errors. Everything works fine if have the script backup Postgres and just send a log, but not if I have it email the backup file. Any ideas why the email attachment is not working?
SOLVED: Changed the order of "$BACKUPFILES $MAILADDR < $LOGFILE" to "$MAILADDR $BACKUPFILES < $LOGFILE" for mutt, and this stopped mutt from trying to attached the email address as an attachment, and thus failing.
Like so:
mutt -s "PostgreSQL Backup Log and SQL Files for $HOST - $DATE" $MAILADDR $BACKUPFILES < $LOGFILE
Related
I'm working on a script to monitor a log of jobs executed and I want to receive a mail notification with the line where appears the job in the body of the mail. This is what I got so far but it keeps throwing error, I can make it work but just with an empty body. Could you please help?
Job="jobname"
tail -fn0 logfile.log | awk -v Jobs="$Job"'/jobname/
{
system("grep -i "Jobs" logfile.log | mail -s "Jobs Is Completed" mail#mail.com")
exit
}'
What's wrong with just:
Job="jobname"
tail -fn0 logfile.log |
grep --line-buffered -i "jobname.*$Job" |
mail -s "$Job Is Completed" mail#mail.com"
Your use of jobname as literal in 2 places and a shell variable named Job with an awk variable named Jobs populated from it and both containing jobname anyway was very confusing so hopefully you can tweak the above to do whatever you need to do if the variable usage above is not quite right.
watchdog.sh
#!/bin/bash
mailWorker(){
while read -r line; do
if [[ $line == *$match* ]]
then
# mailing
grep -i "Jobs" "$logfile" | mail -s "Jobs Is Completed" mail#mail.com
break
fi
done
}
logfile="/path/to/logfile.log"
match="jobname"
if [ ! -f "$logfile" ]; then
touch "$logfile"
fi
tail -f --lines=0 "$logfile" | mailWorker
I'm building an haproxy config file that has multiple front and backends. It's going to be several hundred lines long and I'd rather split it up into separate files for each of the different websites that I want to loadbalance.
Does HAProxy offer the ability to link to partial config files from the main haproxy.cfg file?
Configuration files can't be linked together from a configuration directive.
However HAProxy can load multiple configuration files from its command line, using the -f switch multiple times:
haproxy -f conf/http-defaults -f conf/http-listeners -f conf/tcp-defaults -f conf/tcp-listeners
If you want to be flexible with the amount of config files you can even specify a directory like this: -f /etc/haproxy. The files will then be used in their lexical order, newer files overriding older files.
See the mailing list for an example, if provides links to the documentation. This information can be found in the management guide, not the regular docs.
Stumbled on this answer where the author created scripts to imitate nginx disable enable sites functionality. In the haproxy init.d startup he uses script loop to build the haproxy -f commands concatenation.
/etc/init.d/haproxy:
EXTRAOPTS=`for FILE in \`find /etc/haproxy/sites-enabled -type l | sort
-n\`; do CONFIGS="$CONFIGS -f $FILE"; done; echo $CONFIGS`
haensite script:
#!/bin/bash
if [[ $EUID -ne 0 ]]; then
echo "You must be a root user" 2>&1
exit 1
fi
if [ $# -lt 1 ]; then
echo "Invalid number of arguments"
exit 1
fi
echo "Enabling $1..."
cd /etc/haproxy/sites-enabled
ln -s ../sites-available/$1 ./
echo "To activate the new configuration, you need to run:"
echo " /etc/init.d/haproxy restart"
hadissite script:
#!/bin/bash
if [[ $EUID -ne 0 ]]; then
echo "You must be a root user" 2>&1
exit 1
fi
if [ $# -lt 1 ]; then
echo "Invalid number of arguments"
exit 1
fi
echo "Disabling $1..."
rm -f /etc/haproxy/sites-enabled/$1
echo "To activate the new configuration, you need to run:"
echo " /etc/init.d/haproxy restart"
This was a solution building off of #stephenmurdoch's answer which involved the use of multiple -f <conf file> arguments to the haproxy executable.
Using the stock CentOS 6.x RPM's included /etc/init.d/haproxy script you can amend it like so:
start() {
$exec -c -q -f $cfgfile $OPTIONS
if [ $? -ne 0 ]; then
echo "Errors in configuration file, check with $prog check."
return 1
fi
echo -n $"Starting $prog: "
# start it up here, usually something like "daemon $exec"
#daemon $exec -D -f $cfgfile -f /etc/haproxy/haproxy_ds.cfg -f /etc/haproxy/haproxy_es.cfg -f /etc/haproxy/haproxy_stats.cfg -p $pidfile $OPTIONS
daemon $exec -D -f $cfgfile $(for i in /etc/haproxy/haproxy_*.cfg;do echo -n "-f $i ";done) -p $pidfile $OPTIONS
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
With the above in place you can then create files such as haproxy_<X>.cfg and haproxy_<Y>.cfg using whatever names you want. The above for loop will include these files in an augmented daemon haproxy ... line if these files are present, otherwise the stock haproxy.cfg file will be used solely.
Within the haproxy_<...>.cfg files you need to make sure that your global and defaults are defined in the "toplevel" haproxy.cfg file. The rest of the files simply need to have frontend/backends and nothing more.
You can follow this simple step.
Insert one line script (cat /etc/$BASENAME/conf.d/*.cfg > $CFG) in /etc/init.d/haproxy
Here is position where you must insert line
CFG=/etc/$BASENAME/$BASENAME.cfg
cat /etc/$BASENAME/conf.d/*.cfg > $CFG
[ -f $CFG ] || exit 1
Reload daemon config with systemctl daemon-reload
Make directory mkdir /etc/haproxy/conf.d
Move default haproxy.cfg to conf.d as global.cfg mv /etc/haproxy/haproxy.cfg /etc/haproxy/conf.d/global.cfg
Create your other .cfg file in conf.d directory
Just restart your haproxy service systemctl restart haproxy
NOTE: /etc/haproxy/haproxy.cfg will be automaticly created from all files in conf.d/
answer of #Bapstie memtioned that, a directory can be passed to haproxy as config file, and files inside will be loaded in alphabet order. It's correct.
But problem is, the package haproxy in CentOS 'base/7/x86_64' repository is so old that it does not support that.
So either do you need to write a wrapper to append -f <individual config file>to the command, or you need to install latest version of haproxy:
for package in centos-release-scl-rh rh-haproxy18-haproxy; do
yum install -y $package
done
and create a drop-in config for haproxy service:
[Service]
ExecStart=
ExecStart=/opt/rh/rh-haproxy18/root/sbin/haproxy -f /etc/haproxy-nutstore/ -p /run/haproxy.pid $OPTIONS
If you use Ansible you can do a trick like this:
- name: haproxy configuration
copy:
content: >
{{ lookup('template', haproxy_cfg_src_top) +
lookup('template', haproxy_cfg_src_edge) +
lookup('template', haproxy_cfg_src_bottom) }}
dest: "{{ haproxy_cfg }}"
owner: "{{ docker_user }}"
group: "docker"
mode: 0664
register: haproxy_cfg_change
Using sh on linux I am looking to output the results from multiple if statements to a mail message.
#snap server1
running=`ps -U server1 | wc -l`
if [ $running -eq 1 ]; then
/root/zfsnap/zfSnap.sh -v -a 30d tank/server1
fi
#snap server2
running=`ps -U server2 | wc -l`
if [ $running -eq 1 ]; then
/root/zfsnap/zfSnap.sh -v -a 30d tank/server2
fi
sleep 3 && echo "results of script" | mail -s "snapshot status" administrator#domain.local
## current output is
[root#backupserver ~]# ./backup_script_daily.sh
/sbin/zfs snapshot tank/server1#2013-08-26_12.28.22--30d ... DONE
/sbin/zfs snapshot tank/server2#2013-08-26_12.28.22--30d ... DONE
I'm not really sure how to do this for multiple if statements. I've seen many discussions on individual if statements. I actually have about 8 more (user/servers) in this script. My scripting experience for years has been very low level :). Would it be better to use something like Perl
put servers into array
for each server in array
run command > to text file
end and mail(textfile)
I appreciate any suggestions or ideas and I apologize for any issues with the post. This is my first one.
Kind Regards,
~Jon R.
You can enclose all commands whose output you want to capture in a { } block and pipe the whole thing into the mail command, e.g.:
#!/bin/bash
{
for server in server{1..2}; do
if (( $(pgrep -U "${server}" 2>/dev/null | wc -l) > 0 )); then
/root/zfsnap/zfSnap.sh -v -a 30d "tank/${server}"
fi
done
} | mail -s "snapshot status" administrator#domain.local
I am running a program on my machine that is triggered by running a .bat file. Right now, I am manually modifying the .bat to point to specific files/folders before running the script, which only takes a few minutes since I am running this on 3 to 4 files at a time. In the very near future, I am going to need to run this script on groups of files ranging from 200 to 500. Manually trying to edit the .bat file each time would be a nightmare.
The finished .bat would look like:
cd\[rootfolder]
mkdir Output
cd\folderpath\to\program
this.is.the.program.exe -i "[rootfolder]\[filename1].pdf" -r "[rootfolder]" -o "[rootfolder]\Output" -u username -p password
this.is.the.program.exe -i "[rootfolder]\[filename2].pdf" -r "[rootfolder]" -o "[rootfolder]\Output" -u username -p password
this.is.the.program.exe -i "[rootfolder]\[filename3].pdf" -r "[rootfolder]" -o "[rootfolder]\Output" -u username -p password
this.is.the.program.exe -i "[rootfolder]\[filename4].pdf" -r "[rootfolder]" -o "[rootfolder]\Output" -u username -p password
What I would like to do is create another script, .ps or .bat, that will take a list of filenames from a .txt file (dir /b output) and add the information from above in the correct place.
cd\[rootfolder]
mkdir Output
cd\folderpath\to\program
would only occur in the head of the script; This can be done in another way, but if it is included, that is fine...
this.is.the.program.exe -i "[rootfolder]\
would be added before each filename in the .txt file; I can manage this so far with a search/replace operation...
.pdf" -r "[rootfolder]" -o "[rootfolder]\Output" -u username -p password
would be added behind the filename. This is where I am having the issue!
The only similarity to the files will be the beginning of the filename; such as "Text_", which is why I can do a search/replace operation. The ending of the files are completely random and could be alpha, numeric or symbols, and could be of any character length.
I guess my question would be:
Is there a way to insert text into a .txt file by line position or something similar? Behind the last character on each line?
try this:
cd /d "rootfolder"
md output
for %%a in (*.pdf) do "folderpath\to\program\this.is.the.program.exe" -i "%%~a" -r "rootfolder" -o "rootfolder\Output" -u username -p password
or this:
cd /d "rootfolder"
md output
cd /d "folderpath\to\program"
for %%a in ("rootfolder\*.pdf") do "this.is.the.program.exe" -i "%%~a" -r "%%~dpa" -o "%%~dpaOutput" -u username -p password
In powershell you'd probably do something like this:
$rootfolder = 'C:\path\to\rootfolder'
$outputfolder = Join-Path $rootfolder 'Output'
$programfolder = 'C:\program\folder'
$filelist = 'C:\path\to\files.txt'
$user = 'username'
$pass = 'password'
if ( -not (Test-Path -LiteralPath $outputfolder) ) {
New-Item -ItemType directory -Path $outputfolder
}
Set-Location $programfolder
Get-Content $filelist | % {
.\this.is.the.program.exe -i (Join-Path $rootfolder $_) -r $rootfolder `
-o $outputfolder -u $user -p $pass
}
cd\[rootfolder]
mkdir Output
cd\folderpath\to\program
for /f "delims=" %%a in (
' the dir /b command that generates the .txt file '
) do (
this.is.the.program.exe -i "[rootfolder]\%%a.pdf" -r "[rootfolder]" -o "[rootfolder]\Output" -u username -p password
)
should execute this requirement.
i want to tail log file with grep and sent it via mail
like:
tail -f /var/log/foo.log | grep error | mail -s subject name#example.com
how can i do this?
You want to send an email when emailing errors occur? That might fail ;)
You can however try something like this:
tail -f $log |
grep --line-buffered error |
while read line
do
echo "$line" | mail -s subject "$email"
done
Which for every line in the grep output sends an email.
Run above shell script with
nohup ./monitor.sh &
so it will keep running in the background.
I'll have a go at this. Perhaps I'll learn something if my icky bash code gets scrutinised. There is a chance there are already a gazillion solutions to do this, but I am not going to find out, as I am sure you have trawled the depths and widths of the cyberocean. It sounds like what you want can be separated into two bits: 1) at regular intervals obtain the 'latest tail' of the file, 2) if the latest tail actually exists, send it by e-mail. For the regular intervals in 1), use cron. For obtaining the latest tail in 2), you'll have to keep track of the file size. The bash script below does that - it's a solution to 2) that can be invoked by cron. It uses the cached file size to compute the chunk of the file it needs to mail. Note that for a file myfile another file .offset.myfile is created. Also, the script does not allow path components in the file name. Rewrite, or fix it in the invocation [e.g. (cd /foo/bar && segtail.sh zut), assuming it is called segtail.sh ].
#!/usr/local/bin/bash
file=$1
size=0
offset=0
if [[ $file =~ / ]]; then
echo "$0 does not accept path components in the file name" 2>&1
exit 1
fi
if [[ -e .offset.$file ]]; then
offset=$(<".offset.$file")
fi
if [[ -e $file ]]; then
size=$(stat -c "%s" "$file") # this assumes GNU stat, possibly present as gstat. CHECK!
# (gstat can also be Ganglias Status tool - careful).
fi
if (( $size < $offset )); then # file might have been reduced in size
echo "reset offset to zero" 2>&1
offset=0
fi
echo $size > ".offset.$file"
if [[ -e $file && $size -gt $offset ]]; then
tail -c +$(($offset+1)) "$file" | head -c $(($size - $offset)) | mail -s "tail $file" foo#bar
fi
How about:
mail -s "catalina.out errors" blah#myaddress.com < grep ERROR catalina.out