#!/bin/bash
# /usr/local/bin/blog
# https://crystalfaeries.net/posix/bin/blog
# celeste:crystalfaery BLOG 2017-12-12 21:12:20+00:00
# This is a blog maintenance wrapper around (the PERL program) "chronicle"
# highly customized for https://crystalfaeries.net/
#
# Other than the usual help and version options, we accept:
# -e or --edit to request an interactive edit of the blog source (todo's)
# -l or --links to request link validation at end of run
let help=11 # this line # - 1
umask 2 # NOT world writeable
false # default to non interactive (e.g. executed as a cron job)
let edit=$? # default to non interactive (e.g. executed as a cron job)
false
let links=$? # default to not checking links
while [ $# -ne 0 ]
do
case $# in
0 | 1 | 2) case "${1}" in
-h | --help)
head -n ${help} $0
exit;;
-v | --version)
head -n ${help} $0
exit;;
-e | --edit)
true
let edit=$? # user wants an interactive edit of the blog source
shift;;
-l | --links)
true
let links=$? # user wants us to check our links
shift;;
*) echo "$0 does not cognize ${@}" 1>&2
shift # pedantic
exec $0 -h # cluestick
;; # nevermore
esac;;
*) echo "$0 does not take $# arguments" 1>&2
shift # pedantic
exec $0 -h # cluestick
;;
esac
done
####### BLOG BEGIN #######
cat /var/log/chronicle.log > \
/var/log/chronicle.log- \
2>> /var/log/chronicle.log || exit -1 # Error: 255 Require writeable log backup
echo "################################################################################################" \
2> /var/log/chronicle.log 1>&2 || exit -1 # Error: 255 Require writeable log file
echo "`now` BLOG START" \
2>> /var/log/chronicle.log 1>&2 || exit -2 # Error: 254 Require "now" for time-tagging
# we are keeping only a subset or differing hierarchy structure of clairvoyance, audio, video, pdf, so beware changes:
echo 'rsync -auvzH divservi@box6537.bluehost.com:~/crystalfaeries.net/{.??*,*.txt,*.html,fae,src} ${HOME}/crystalfaeries.net' 2>> /var/log/chronicle.log 1>&2
rsync -auvzH divservi@box6537.bluehost.com:~/crystalfaeries.net/{.??*,*.txt,*.html,fae,src} ${HOME}/crystalfaeries.net 2>> /var/log/chronicle.log 1>&2
# echo 'KKCR Subscriptions' 2>> /var/log/chronicle.log 1>&2
subscriptions > ${HOME}/crystalfaeries.net/audio/kkcr/subscriptions.html 2>> /var/log/chronicle.log
echo 'ASTROLOG' 2>> /var/log/chronicle.log 1>&2
astrolog 2>> /var/log/chronicle.log 1>&2
echo 'HCAL BEGIN' 2>> /var/log/chronicle.log 1>&2
hcal > ${HOME}/crystalfaeries.net/hcal.html \
2>> /var/log/chronicle.log || exit -56 # Error: 200
echo 'CLEAR TRASH' 2>> /var/log/chronicle.log 1>&2
rm -rf /home/{crystalfaeries.net,www}/.Trash-${UID} \
2>> /var/log/chronicle.log 1>&2
echo 'PERMISSIONS BEGIN' 2>> /var/log/chronicle.log 1>&2
# NOTE: Once this is run manually to get permissions correct, subsequent invocations by cron should work.
# Goto the Blog Source directory where we edit most files of blog
cd -P ${HOME}/crystalfaeries.net/src/ \
2>> /var/log/chronicle.log 1>&2 || exit -3 # Error: 253 Require blog source directory
# NOTE: if we link posix/ to /usr/local, beware making /usr/local/bin/* UN-executable!
# Force Permissions (private content is only available as file:///)
# we try to be silent and not require sudo password, but will retry with it if necessary
find ${HOME}/crystalfaeries.net/ /home/{audio,video}/www/ -type d \! -perm 2775 \
\! -name celeste \
\! -name src \
-print -exec chmod 2775 {} \; \
2>> /var/log/chronicle.log 1>&2 || \
sudo find ${HOME}/crystalfaeries.net/ /home/{audio,video}/www/ -type d \! -perm 2775 \
\! -name celeste \
\! -name src \
-print -exec chmod 2775 {} \; \
2>> /var/log/chronicle.log 1>&2 || exit -4 # Error: 252 Permissions Unsettable
# index.html hides ALL private content from http://
# only access to private content is file:///
chmod 771 ${HOME}/crystalfaeries.net/celeste \
2>> /var/log/chronicle.log 1>&2 || \
sudo chmod 771 ${HOME}/crystalfaeries.net/celeste \
2>> /var/log/chronicle.log 1>&2 || exit -5 # Error: 251 Permissions Unsettable
chmod 770 ${HOME}/crystalfaeries.net/src \
2>> /var/log/chronicle.log 1>&2 || \
sudo chmod 770 ${HOME}/crystalfaeries.net/src \
2>> /var/log/chronicle.log 1>&2 || exit -6 # Error: 250 Permissions Unsettable
find ${HOME}/crystalfaeries.net/ /home/{audio,video}/www/ -type f \! -perm 664 \
\! -name '.??*' \
-print -exec chmod 664 {} \; \
2>> /var/log/chronicle.log 1>&2 || \
sudo find ${HOME}/crystalfaeries.net/ /home/{audio,video}/www/ -type f \! -perm 664 \
\! -name '.??*' \
-print -exec chmod 664 {} \; \
2>> /var/log/chronicle.log 1>&2 || exit -7 # Error: 249 Permissions Unsettable
# ToDo (.??*) Files:
find ${HOME}/crystalfaeries.net/src/ -type f \! -perm 660 \
-name '.??*' \
-print -exec chmod 660 {} \; \
2>> /var/log/chronicle.log 1>&2 || \
sudo find ${HOME}/crystalfaeries.net/src/ -type f \! -perm 660 \
-name '.??*' \
-print -exec chmod 660 {} \; \
2>> /var/log/chronicle.log 1>&2 || exit -8 # Error: 248 Permissions Unsettable
echo 'EXPIRE BEGIN' 2>> /var/log/chronicle.log 1>&2
# EXPIRE Articles containing "Expiry:" entry
pushd ${HOME} >& /dev/null || exit -9 # Error: 247 /usr/local/bin/delete only works in home directory until we recode it
for f in $(grep '^Expiry: ' ${HOME}/crystalfaeries.net/src/*.txt | sed 's/:.*$//')
do
if [ $(date +%s) -gt $(grep '^Expiry: ' ${f} | cut -f2-) ]
then # this article is beyond its expiry timestamp
echo "Expired: ${f}" >> /var/log/chronicle.log 2>&1
delete ${f} >> /var/log/chronicle.log 2>&1
else # this article is within its limited lifespan
echo "Visible: ${f}" >> /var/log/chronicle.log 2>&1
fi
done
popd >& /dev/null || exit -9 # Error: 247 back to chronicle blog source
# Unless the user erred in article creation, Expiry should post-date Publish date, right?
# So above we only expired already published articles, not Future Publish articles we may now reveal.
echo 'REVEAL BEGIN' 2>> /var/log/chronicle.log 1>&2
# NOTE: User may PREVIEW hidden files with /usr/local/bin/preview in ${HOME}/crystalfaeries.net/fay/
# User may generate "tomorrow's" blog entry as a hidden file
# which is not published by chronicle until first run of publish date:
rsync -auvzH .`date +'%Y-%m-%d'`.fae.txt \
`date +'%Y-%m-%d'`.fae.txt 2>> /var/log/chronicle.log 1>&2 \
&& touch ${HOME}/crystalfaeries.net/src
rm .`date +'%Y-%m-%d'`.fae.txt 2>> /var/log/chronicle.log 1>&2 \
&& touch ${HOME}/crystalfaeries.net/src
# UNCOMMENT THIS SECTION TO DAILY GENERATE DEFAULT TEMPLATE ARTICLE
# WHICH CAN ALSO BE GENERATED BY THE SCRIPT "today"
# if [ \! -f `date +'%Y-%m-%d'`.fae.txt ]
# then # generate default file if user did not pre-pare today's blog entry
# echo "Date: `date -u --rfc-3339=seconds | sed 's/ .*$/ 10:00:00+00:00/'`" \
# > `date +'%Y-%m-%d'`.fae.txt # dated as of beginning of day in local TZ
# cat ${HOME}/crystalfaeries.net/src/.template.txt >> `date +'%Y-%m-%d'`.fae.txt \
# 2>> /var/log/chronicle.log || exit -10 # Error: 246 Default Template
# touch ${HOME}/crystalfaeries.net/src
# fi
preview 2>> /var/log/chronicle.log 1>&2 # Update Previews of Future Blog Entries
if [ ${edit} -eq 0 ]
then # User wants an interactive edit session of blog source
pushd ~ 2>> /var/log/chronicle.log 1>&2 # Go Home to be able to delete while editing
todo # edit today's entry, and see ToDo's before updating blog
popd 2>> /var/log/chronicle.log 1>&2 # Return to Blog Source Directory
fi
# if [ $(date +%s -r ${HOME}/crystalfaeries.net/src) -gt $(date +%s -r ${HOME}/crystalfaeries.net/fae) ]
# then # source is newer than HTML (see /etc/chroniclerc for pre and post touch ops)
echo "`now` CHRONICLE START" 2>> /var/log/chronicle.log 1>&2 || exit -11 # Error: 245 Chronicle Error
chronicle --verbose 2>> /var/log/chronicle.log 1>&2
let chroniclereturn=${?}
if [[ ${chroniclereturn} -eq 0 ]]
then
echo "`now` CHRONICLE END" 2>> /var/log/chronicle.log 1>&2 || exit -12 # Error: 244 Chronicle Error
else
echo "`now` CHRONICLE ERROR: ${chroniclereturn}" 2>> /var/log/chronicle.log 1>&2 || exit -13 # Error: 243 Chronicle Error
fi
sed -i 's/No tags/<hr align="center" width="100%">/g' \
${HOME}/crystalfaeries.net/fae/{*.html,archive/*/*/*.html} \
2>> /var/log/chronicle.log || exit -14 # Error: 242 SiteMap Error
gzip -c ${HOME}/crystalfaeries.net/fae/sitemap.xml > ${HOME}/crystalfaeries.net/sitemap.xml.gz \
2>> /var/log/chronicle.log || exit -15 # Error: 241 SiteMap Error
recently_linked \
2>> /var/log/chronicle.log || exit -16 # Error: 240 Recently Updated Error
recently_updated \
2>> /var/log/chronicle.log || exit -17 # Error: 239 Recently Updated Error
# fi
######################################
######################################
# BEWARE WE DELETE ALL BUT EXCLUDED! #
######################################
######################################
# do not remove any of the --exclude's just below without carefuly analysis!
# this IS a problem because we are keeping only a SUBSET of server contents on source laptop!
# OR because we have differing file hierarchies between laptop and server.
echo 'UPLOAD SRC + HTML TO SERVER' 2>> /var/log/chronicle.log 1>&2 # BEWARE WE DELETE ALL BUT EXCLUDED!
rsync -auvzH --delete \
--exclude='.*.swp' \
--exclude=audio \
--exclude=clairvoyance \
--exclude=clipart \
--exclude=fay \
--exclude=icons \
--exclude=imgs \
--exclude=lost+found \
--exclude=pdf \
--exclude=posix \
--exclude=video \
${HOME}/crystalfaeries.net/.??* \
${HOME}/crystalfaeries.net/* \
divservi@box6537.bluehost.com:~/crystalfaeries.net 2>> /var/log/chronicle.log 1>&2
echo 'UPLOAD CLAIRVOYANCE CLASSES HTML + TXT TO SERVER' 2>> /var/log/chronicle.log 1>&2
rsync -auvzH ${HOME}/crystalfaeries.net/clairvoyance/*.{html,txt} \
divservi@box6537.bluehost.com:~/crystalfaeries.net/clairvoyance \
2>> /var/log/chronicle.log 1>&2
echo 'GALLERIES BEGIN' 2>> /var/log/chronicle.log 1>&2
cd -P ${HOME}/crystalfaeries.net/imgs/ \
2>> /var/log/chronicle.log 1>&2 || exit -17 # Error: 239 Image Directory Permissions Error
if [ 0 -ne $(find . -maxdepth 1 -type f -newer HEADER.html \
\! -name astro.bmp \
\! -name moon.png \
2>> /var/log/chronicle.log \
| /usr/bin/wc \
| /bin/sed 's/^ *//g;s/ .*$//g') ]
then # have new image file other than
# the /usr/local/bin/astrolog generated astrological image or
# the /usr/bin/pngphoon generated moon image
echo "index being updated: `pwd`" 2>> /var/log/chronicle.log 1>&2 || exit -18 # Error: 238 Require writeable log file
cp ../HEADER.html HEADER.html # no output unless image files present
igal2 -i HEADER.html \
2>> /var/log/chronicle.log 1>&2 # || exit -19 # Error: 237 igal2 /imgs/HEADER.html
cat ~/crystalfaeries.net/README.html >> HEADER.html \
2>> /var/log/chronicle.log || exit -20 # Error: 236 igal2 /imgs/HEADER.html
echo "index was updated in `pwd`" 2>> /var/log/chronicle.log 1>&2 || exit -21 # Error: 235 Require writeable log file
else # ok
echo "index is current in: `pwd`" 2>> /var/log/chronicle.log 1>&2 || exit -22 # Error: 234 Require writeable log file
fi
echo 'SUBGALLERIES BEGIN' 2>> /var/log/chronicle.log 1>&2
# DO NOT alter these hand-built directories: ${HOME}/crystalfaeries.net/imgs/{bettie+ets,coins,puthg}
# NOTE the imgs/coins directory is entirely manually managed for /fae/lawful_money.html
# DO NOT imagescape these directories (see also: ${HOME}/crystalfaeries.net/imgs/.exclude):
for d in ${HOME}/crystalfaeries.net/clipart \
${HOME}/crystalfaeries.net/imgs/{3d2,astro,landscape,portrait}
do
cd -P ${d} # note we expect ABSOLUTE PATHS!
# do we have updates in this directory? (including deletions)
if [ 0 -eq $(find . -newer index.html 2> /dev/null | /usr/bin/wc | /bin/sed 's/^ *//g;s/ .*$//g' 2>> /var/log/chronicle.log) ]
then
echo "index is current in: `pwd`" 2>> /var/log/chronicle.log 1>&2 || exit -23 # Error: 233 Require writeable log file
else
echo "index being updated: `pwd`" 2>> /var/log/chronicle.log 1>&2 || exit -24 # Error: 232 Require writeable log file
# remove the old index files as any file addition or deletion shifts gallery entries
find . -iname '*.html' \
\! -name HEADER.html \
\! -name README.html \
\! -name .indextemplate2.html \
\! -name .slidetemplate2.html \
\! -name .tile.png \
-exec rm {} \; \
2>> /var/log/chronicle.log 1>&2
# remove all thumbnails as obsolete or orphanned
rm .thumb_* \
2>> /var/log/chronicle.log 1>&2
# generate new thumbnails and index files
cp /dev/null index.html # no output unless image files present
/usr/bin/igal2 \
2>> /var/log/chronicle.log 1>&2 # || exit -25 # Error: 231 Image Gallery Error
# prepend our HEADER in front of igal2's index and postpend README, leaving index.html as newer than .
cat {HEADER,index,${HOME}/crystalfaeries.net/README}.html > \
/tmp/$$.html \
2>> /var/log/chronicle.log # Do we ALWAYS HAVE an HEADER file?
cat /tmp/$$.html > index.html \
2>> /var/log/chronicle.log || exit -26 # Error: 230 Image Gallery Error
echo "index was updated in `pwd`" 2>> /var/log/chronicle.log 1>&2 || exit -27 # Error: 229 Require writeable log file
fi
done
# Namlu'u Gallery is NOT imagescaped, has custom index
echo "Namlu'u GALLERY BEGIN" 2>> /var/log/chronicle.log 1>&2
cd ~/crystalfaeries.net/imgs/namluu
cat HEADER.html \
> /tmp/index.html
rm .thumb_* ?.html ??.html ???.html \
index.html
igal2
tail -n +18 index.html \
>> /tmp/index.html
cat ~/crystalfaeries.net/README.html \
>> /tmp/index.html
cat /tmp/index.html \
> index.html
# DO imagescape these directories:
echo 'imagescape GALLERIES BEGIN' 2>> /var/log/chronicle.log 1>&2
for d in $(cat ${HOME}/crystalfaeries.net/imgs/.include)
do
cd -P ${HOME}/crystalfaeries.net/imgs/${d} # NOTE DIRECTORIES RELATIVE TO imgs directory
# do we have updates in this directory? (including deletions)
if [ 0 -eq $(find . -newer index.html 2>> /var/log/chronicle.log | /usr/bin/wc | /bin/sed 's/^ *//g;s/ .*$//g' 2>> /var/log/chronicle.log) ]
then
echo "index is current in: `pwd`" 2>> /var/log/chronicle.log 1>&2 || exit -23 # Error: 233 Require writeable log file
else
echo "index being updated: `pwd`" 2>> /var/log/chronicle.log 1>&2 || exit -24 # Error: 232 Require writeable log file
# remove the old index files as any file addition or deletion shifts gallery entries
# find . -iname '*.html' \
# \! -name HEADER.html \
# \! -name README.html \
# \! -name .indextemplate2.html \
# \! -name .slidetemplate2.html \
# \! -name .tile.png \
# -exec rm {} \; \
# 2>> /var/log/chronicle.log 1>&2
# remove index pages
rm ?.html ??.html ???.html ????.html \
2>> /var/log/chronicle.log 1>&2
# remove all thumbnails as obsolete or orphanned
rm .thumb_* \
2>> /var/log/chronicle.log 1>&2
# imagescape the directory
imagescape . 2>>/var/log/chronicle.log # hardlink in subdirectories from un-sorted files
# generate new thumbnails and index files
cp /dev/null index.html 2>> /var/log/chronicle.log 1>&2 # no output unless image files present
/usr/bin/igal2 \
2>> /var/log/chronicle.log 1>&2 # || exit -25 # Error: 231 Image Gallery Error
# prepend our HEADER in front of igal2's index leaving index.html as newer than .
cat {HEADER,index,${home}/crystalfaeries.net/README}.html > /tmp/$$.html \
2>> /var/log/chronicle.log # Do we ALWAYS HAVE an HEADER file?
cat /tmp/$$.html > index.html \
2>> /var/log/chronicle.log || exit -26 # Error: 230 Image Gallery Error
echo "index was updated in `pwd`" 2>> /var/log/chronicle.log 1>&2 || exit -27 # Error: 229 Require writeable log file
# update the subdirectories
for d in landscape portrait
do
if [ -d $d ]
then
pushd $d 2>> /var/log/chronicle.log 1>&2 || exit -25 # Error: 231
# remove index pages
rm ?.html ??.html ???.html ????.html 2>> /var/log/chronicle.log 1>&2 # || exit -25 # Error: 231
# remove all thumbnails as obsolete or orphanned
rm .thumb_* 2>> /var/log/chronicle.log 1>&2 # || exit -25 # Error: 231
# generate the new gallery index
/usr/bin/igal2 2>> /var/log/chronicle.log 1>&2 # || exit -25 # Error: 231
popd 2>> /var/log/chronicle.log 1>&2 || exit -25 # Error: 231
fi
done
fi
done
# fdedupe the website
cd -P ${HOME}/crystalfaeries.net/ \
2>> /var/log/chronicle.log 1>&2 || exit -45 # Error: 211
for i in {1..9}
do
fdedupe -f \
2>> /var/log/chronicle.log 1>&2 || exit -53 # Error: 203
done
echo 'UPLOAD CLIPART TO SERVER' 2>> /var/log/chronicle.log 1>&2 # BEWARE WE DELETE ALL BUT EXCLUDED!
echo 'rsync -auvzH --delete ${HOME}/crystalfaeries.net/clipart divservi@box6537.bluehost.com:~/crystalfaeries.net' 2>> /var/log/chronicle.log 1>&2
rsync -auvzH --delete ${HOME}/crystalfaeries.net/clipart divservi@box6537.bluehost.com:~/crystalfaeries.net 2>> /var/log/chronicle.log 1>&2
echo 'UPLOAD IMGS+PDFs TO SERVER' 2>> /var/log/chronicle.log 1>&2
pushd ${HOME}/crystalfaeries.net/pdf 2>> /var/log/chronicle.log 1>&2
tree -Fht -T "crystalfaeries pdfs+epubs (most recent on top)" \
-H http://crystalfaeries.net/pdf > index.html 2>> /var/log/chronicle.log
popd 2>> /var/log/chronicle.log 1>&2
echo 'rsync -auvzH ${HOME}/crystalfaeries.net/{imgs,pdf} divservi@box6537.bluehost.com:~/crystalfaeries.net' 2>> /var/log/chronicle.log 1>&2
rsync -auvzH ${HOME}/crystalfaeries.net/{imgs,pdf} divservi@box6537.bluehost.com:~/crystalfaeries.net 2>> /var/log/chronicle.log 1>&2
echo 'AGGREGATE BACKUP TO "secure" DISK' 2>> /var/log/chronicle.log 1>&2
mkdir -p /home/www 2>> /var/log/chronicle.log 1>&2
find /home/www -type l -print -exec rm {} \; 2>> /var/log/chronicle.log 1>&2
echo "rsync -auvzH --delete --exclude='.*.swp' --exclude=audio --exclude=clairvoyance --exclude=fay --exclude=imgs/3d2 --exclude=imgs/3dc --exclude=linkdoc --exclude=pdf --exclude=posix --exclude=video ${HOME}/crystalfaeries.net/{.??,}* /home/www" \
2>> /var/log/chronicle.log 1>&2
rsync -auvzH --delete \
--exclude='.*.swp' \
--exclude=audio \
--exclude=clairvoyance \
--exclude=fay \
--exclude=imgs/3d2 \
--exclude=imgs/3dc \
--exclude=imgs/legshow \
--exclude=linkdoc \
--exclude=pdf \
--exclude=posix \
--exclude=video \
${HOME}/crystalfaeries.net/{.??,}* /home/www 2>> /var/log/chronicle.log 1>&2
# fdedupe the web backup
cd -P /home/www \
2>> /var/log/chronicle.log 1>&2 || exit -57 # Error: 199
for i in {1..9}
do
fdedupe -f \
2>> /var/log/chronicle.log 1>&2 || exit -58 # Error: 198
done
# back to the website
cd -P ${HOME}/crystalfaeries.net/ \
2>> /var/log/chronicle.log 1>&2 || exit -59 # Error: 197
echo 'UPLOAD MEDIA TO SERVER' 2>> /var/log/chronicle.log 1>&2 # NOT YET DELETING
rsync -auvzH /home/audio/www/* divservi@box6537.bluehost.com:~/crystalfaeries.net/audio \
2>> /var/log/chronicle.log 1>&2
rsync -auvzH /home/video/www/* divservi@box6537.bluehost.com:~/crystalfaeries.net/video \
2>> /var/log/chronicle.log 1>&2
echo "ssh -t divservi@box6537.bluehost.com 'find ~/crystalfaeries.net/ -type d \! -perm 2775 -print -exec chmod 2775 {} \;'" \
2>> /var/log/chronicle.log 1>&2
ssh -t divservi@box6537.bluehost.com 'find ~/crystalfaeries.net/ -type d \! -perm 2775 -print -exec chmod 2775 {} \;' \
2>> /var/log/chronicle.log 1>&2
echo "ssh -t divservi@box6537.bluehost.com 'find ~/crystalfaeries.net/ -type f \! -perm 664 -print -exec chmod 664 {} \;'" \
2>> /var/log/chronicle.log 1>&2
ssh -t divservi@box6537.bluehost.com 'find ~/crystalfaeries.net/ -type f \! -perm 664 -print -exec chmod 664 {} \;' \
2>> /var/log/chronicle.log 1>&2
echo 'CLEAR SWAP FILES and EMPTY FILES' 2>> /var/log/chronicle.log 1>&2
find /home/{crystalfaeries.net,www}/ -iname '.*.swp' -print -exec rm {} \; \
2>> /var/log/chronicle.log 1>&2
find /home/{crystalfaeries.net,www}/ -depth -type f -size 0 -print -exec rm {} \; \
2>> /var/log/chronicle.log 1>&2
# done updating blog
echo "`now` BLOG END $?" \
2>> /var/log/chronicle.log 1>&2
echo "################################################################################################" \
2>> /var/log/chronicle.log 1>&2 || exit -1 # Error: 255 Require writeable log file
# now it's time to validate our links
if [ ${links} -eq 0 ]
then # User wants links validated
echo "`now` LINK_LINT BEGIN" \
2>> /var/log/chronicle.log 1>&2
link_lint \
2>> /var/log/chronicle.log 1>&2
echo "`now` LINK_LINT END $?" \
2>> /var/log/chronicle.log 1>&2
echo "################################################################################################" \
2>> /var/log/chronicle.log 1>&2 || exit -1 # Error: 255 Require writeable log file
fi
exit $?
syntax highlighted by Code2HTML, v. 0.9.1