Tech in a Galagzee, Not So Far Away.
UNIX
Deleting all network interface aliases
Jul 22nd
I recently needed to move bunch of aliased IPs from one FreeBSD server to another. Adding aliases to /etc/rc.conf and then running ./netstart while in /etc adds new multiplexed IPs to the system all right, but if you need to remove aliased IPs, running /etc/netstart won’t remove them even if the aliases have been removed from /etc/rc.conf. Perhaps there is some easy single command that culls the active alias IPs to those specified in /etc/rc.conf, but I’m not aware of it. The following command can be used to quickly delete all aliased IPs for a specific interface (here “em0″):
ifconfig | grep “0xffffffff” | awk ‘{ print $2 }’ | xargs -n 1 ifconfig em0 delete
For this to work, the netmasks of the aliases and the master IP for the inteface must differ. The netmasks of the aliases are usually set to 255.255.255.255 (hence “0xffffffff”) while the netmask of the master IP is usually something different, specific to your network, e.g. 255.255.255.128 (“0xffffff80″).
Once the above command has been run, /etc/netstart can then be executed to load the remaining or reconfigured aliases (if any) from /etc/rc.conf.
FreeBSD Full / Incremental Filesystem Dump Shell Script
Jul 17th
I wanted to automate filesystem dumps on my servers running FreeBSD 7.2. After some searching I came across Vivek Gite’s FreeBSD Full / Incremental Tape Backup Shell Script which gave me a lot of ideas. Since I’m not using tape as the backup target I wanted to make a script specifically for that purpose while at the same time improve handling of some error conditions (such as, most importantly, checking for a missing level 0 dump before proceeding with an incremental dump) and add some new features such as autoincrement the dump level so that the dump level is not tied to specific day of the week.
Here’s my version of the script. While it bears some resemblance to Vivek’s script, it is largely rewritten. Read the script header for more information.
NOTE! In his comment James pointed out a possible bug in the script. The displayed script indeed had a problem: it was missing a backslash in front of the first dollar sign at:
eval “local fspath=\$${fsname}path”
This was caused by the script display plugin in WordPress that treated the backslash as an escape character (this has now been fixed). To be on the safe side, please download the script as a tarball. To further validate the integrity of the tarball, it should produce a md5 hash of 732ac44f11ba4484be4568e84929bb6a.
| | | copy code | | ? |
| 001 | |
| 002 | #!/bin/sh |
| 003 | |
| 004 | # Autodump 1.5a (released 01 August 2009) |
| 005 | # Copyright (c) 2009 Ville Walveranta |
| 006 | # |
| 007 | # A FreeBSD shell script to dump filesystems with full, and automatically |
| 008 | # incremented incremental backups to a given directory location; this script |
| 009 | # was written with the intent of saving the filesystem dumps not onto a tape |
| 010 | # device but on another hard drive such as a different filesystem on the same |
| 011 | # computer. The resulting dump files can be copied offsite with a separate |
| 012 | # cron job. |
| 013 | # |
| 014 | # This script creates the necessary directory structure below the defined |
| 015 | # 'BASEDIR' as well as the necessary log file. This script also ensures that |
| 016 | # the level 0 dump exists before creating an incremental dump; if it doesn't |
| 017 | # the script automatically erases the incremental files for the current week |
| 018 | # (if any exist) and starts over with a level 0 dump. This way you can start |
| 019 | # using the script on any day of the week and level 0 dump is automatically |
| 020 | # created on the first run. |
| 021 | # |
| 022 | # When ran daily (such as from a cron job), the script creates level 0 dump |
| 023 | # on every Monday (beginning the ISO week), or Sunday (beginning of the U.S. |
| 024 | # week) and an incremental dump on all the other days of each week. The dumps |
| 025 | # are compressed with gzip and saved below the 'BASEDIR' to an automatically |
| 026 | # created directory whose name is derived from the list given in 'FSNAMES'. |
| 027 | # Each week's dumps are organized into subfolders with name YYYY-WW ('WW' |
| 028 | # being the current week). By default three most recent weekly dumps |
| 029 | # (level 0 + incrementals) are retained. |
| 030 | # |
| 031 | # The script maintains each weekly folder's date at the _beginning_ date |
| 032 | # of the dump (i.e. Monday or Sunday of the current week) at 00:00, not |
| 033 | # at the most recent incremental's date/time. |
| 034 | # |
| 035 | # By default the root (/) and usr (/usr) filesystems are dumped. To add more |
| 036 | # add a "friendly name" to the 'FSNAMES' list (it is used for the weekly folder |
| 037 | # names, for dump filenames, and to reference the corresponding mount point |
| 038 | # variable); then add the corresponding mount point variable (i.e. if you |
| 039 | # add "var" to 'FSNAMES', then add a variable varpath=/var). The "path" |
| 040 | # ending of the mount point variable name is required. |
| 041 | # |
| 042 | # Since the number of incremental dumps is limited to nine (level 0 + |
| 043 | # incremental levels 1-9), the script will allow maximum of one dump |
| 044 | # to be created per day. However, since the level incrementing is dynamic |
| 045 | # you can start the script on any day of the week, and run it on any |
| 046 | # number of days during the rest of the week and you'll always get |
| 047 | # level 0 plus the incremental dumps in sequential order. However, The |
| 048 | # new weekly folder is always created on Monday or Sunday (as chosen by |
| 049 | # you). Note that the script determines whether "today's" dump exists |
| 050 | # based on the modification date stamp of the most recent dump. Hence |
| 051 | # it is a good idea to run this script in the early hours of each day |
| 052 | # rather than in the very end of each day. Running the script, for |
| 053 | # example, at 23:50 has the potential to push longer dump processes |
| 054 | # over the midnight and so potentially cause the next day's dump to |
| 055 | # be skipped. |
| 056 | # |
| 057 | # Written for FreeBSD 7.2 but should work on most BSD and *NIX systems with |
| 058 | # minor modifications. |
| 059 | # ------------------------------------------------------------------------- |
| 060 | # Copyright (c) 2009 Ville Walveranta |
| 061 | # <http://my.galagzee.com/2009/07/17/freebsd-dump-filesystem-shell-script> |
| 062 | # This script is licensed under GNU GPL version 2.0 or above, and is provided |
| 063 | # 'as-is' with no warranty which is to say that I'm not liable if it wipes out |
| 064 | # your hard drive clean or doesn't back up your precious data. However, to the |
| 065 | # best or my knowledge it is working as expected -- I'm using it myself. :-) |
| 066 | # ------------------------------------------------------------------------- |
| 067 | # This script was inspired by |
| 068 | # FreeBSD Full / Incremental Tape Backup Shell Script |
| 069 | # by nixCraft project / Vivek Gite |
| 070 | # at <http://bash.cyberciti.biz/backup/freebsd-dump-filesystem-shell-script/> |
| 071 | # ------------------------------------------------------------------------- |
| 072 | |
| 073 | |
| 074 | #### GLOBAL VARIABLES ############################################### |
| 075 | |
| 076 | WEEKSTARTS=Mon # Accepted values are "Mon" (ISO standard) or "Sun" (U.S.) |
| 077 | KEEPDUMPS=30 # in days; this is evaluated on the weekly level per start |
| 078 | # of the week, so '30' keeps 3-4 weekly dumps |
| 079 | BASEDIR=/bak/dumps |
| 080 | GLOBALDUMPOPTS=Lua # add 'n' for wall notifications |
| 081 | LOGFILE=/var/log/dump.log |
| 082 | |
| 083 | # to add more filesystems to be dumped add the dump name in 'FSNAMES' |
| 084 | # and add the corresponding mount point variable (dumpname+path=mountpoint) |
| 085 | FSNAMES="root usr" # this is used for dump directory name |
| 086 | # and to ID the path from a variable below |
| 087 | rootpath=/ |
| 088 | usrpath=/usr |
| 089 | |
| 090 | ##################################################################### |
| 091 | |
| 092 | DUMP=/sbin/dump |
| 093 | GZIP=/usr/bin/gzip |
| 094 | LOGGER=/usr/bin/logger |
| 095 | |
| 096 | WEEKDAY=$(date +"%a") |
| 097 | DATE=$(date +"%Y%m%d") |
| 098 | HUMANDATE=$(date +"%d-%b-%Y") |
| 099 | HUMANDATE=`echo $HUMANDATE | tr '[:lower:]' '[:upper:]'` |
| 100 | HUMANTIME=$(date +"%H:%M (%Z)") |
| 101 | TODAYYR=$(date +"%Y") |
| 102 | TODAYMO=$(date +"%m") |
| 103 | TODAYDT=$(date +"%d") |
| 104 | |
| 105 | # datestamp at midnight today |
| 106 | TODAYSTARTSTAMP=$(date -j +%s "${TODAYYR}${TODAYMO}${TODAYDT}0000") |
| 107 | |
| 108 | # default lastdump to midnight today; it will be checked |
| 109 | # and and adjusted later |
| 110 | LASTDUMP=$TODAYSTARTSTAMP |
| 111 | |
| 112 | # do not crete world-readable dumps! |
| 113 | umask 117 |
| 114 | |
| 115 | # make sure the logfile exists |
| 116 | if [ ! -e $LOGFILE ] ; then |
| 117 | touch $LOGFILE |
| 118 | chmod 660 $LOGFILE |
| 119 | fi |
| 120 | |
| 121 | # make sure that entire week's incremental dumps are deposted |
| 122 | # in the same directory, even when a week spans new year |
| 123 | # NOTE: When the ending year has a partial 53rd week, there |
| 124 | # won't be a dump folder for the first week of the new year. |
| 125 | # The incremental dumps instead complete the 53rd week folder, |
| 126 | # even when the 1st week of the new year begins mid-week. |
| 127 | # However, the dates of the incremental dump files in the |
| 128 | # 53rd week folder correctly reflect the dates of the |
| 129 | # beginning year. |
| 130 | adjust_date(){ |
| 131 | local dateoffset=$1 |
| 132 | local epochnow=$(date +%s) |
| 133 | local offsetsecs=`expr $dateoffset "*" 86400` |
| 134 | local newepoch=`expr $epochnow "-" $offsetsecs` |
| 135 | local year=`date -r $newepoch +"%Y"` |
| 136 | |
| 137 | if [ "$WEEKSTARTS" = "Mon" ] ; then |
| 138 | local week=`date -r $newepoch +"%W"` |
| 139 | else |
| 140 | local week=`date -r $newepoch +"%U"` |
| 141 | fi |
| 142 | NEWEPOCHISO=`date -r $newepoch +"%Y%m%d0000"` |
| 143 | |
| 144 | #system week starts from `0', there is no calendar week `0' |
| 145 | week=`expr $week "+" 1` |
| 146 | YWEEK=${year}-${week} |
| 147 | } |
| 148 | |
| 149 | # determines the 'distance' from the level 0 dump in days |
| 150 | if [ "$WEEKSTARTS" = "Mon" ] ; then |
| 151 | case $WEEKDAY in |
| 152 | Mon) adjust_date 0;; |
| 153 | Tue) adjust_date 1;; |
| 154 | Wed) adjust_date 2;; |
| 155 | Thu) adjust_date 3;; |
| 156 | Fri) adjust_date 4;; |
| 157 | Sat) adjust_date 5;; |
| 158 | Sun) adjust_date 6;; |
| 159 | *) ;; |
| 160 | esac |
| 161 | else |
| 162 | case $WEEKDAY in |
| 163 | Sun) adjust_date 0;; |
| 164 | Mon) adjust_date 1;; |
| 165 | Tue) adjust_date 2;; |
| 166 | Wed) adjust_date 3;; |
| 167 | Thu) adjust_date 4;; |
| 168 | Fri) adjust_date 5;; |
| 169 | Sat) adjust_date 6;; |
| 170 | *) ;; |
| 171 | esac |
| 172 | fi |
| 173 | |
| 174 | mk_auto_dump(){ |
| 175 | |
| 176 | local fsname=$1 |
| 177 | |
| 178 | # get the current filesystem's path |
| 179 | # as defined in the corresponding variable |
| 180 | eval "local fspath=\$${fsname}path" |
| 181 | |
| 182 | # composite the dump path |
| 183 | local dumppath=${BASEDIR}/${fsname}/${YWEEK} |
| 184 | |
| 185 | # make sure the dump directory for this week exists; |
| 186 | # this automatically creates a new dump directory on |
| 187 | # every Monday or Sunday (as selected by 'WEEKSTARTS') |
| 188 | [ ! -d $dumppath ] && mkdir -p $dumppath |
| 189 | |
| 190 | # get name of the last file in the current dump directory |
| 191 | local lastfile=`ls -ltr $dumppath | grep -v "^d" | tail -n 1 | awk '{ print $9 }'` |
| 192 | |
| 193 | # assume that the 'lastfile', if it exists, was not created today |
| 194 | local dumped_today=false |
| 195 | |
| 196 | # if a file exists, check its modification date; |
| 197 | # if it is at or after 00:00 today, set a flag to skip the dump |
| 198 | if [ "$lastfile" != "" ] ; then |
| 199 | local fq_lastfile=${dumppath}/$lastfile |
| 200 | if [ -e $fq_lastfile ] ; then |
| 201 | # get the last modification time for the most recently created dumpfile |
| 202 | LASTDUMP=`stat -f %m $fq_lastfile` |
| 203 | if [ $LASTDUMP -ge $TODAYSTARTSTAMP ] ; then |
| 204 | local dumped_today=true |
| 205 | fi |
| 206 | fi |
| 207 | |
| 208 | # get the first and the last dump level for this directory |
| 209 | local levelcommand="ls $dumppath | sed -e 's/^[[:digit:]]*\_//' | sed -e 's/\..*$//'" |
| 210 | local firstlevel=`eval $levelcommand | head -n 1` |
| 211 | local lastlevel=`eval $levelcommand | tail -n 1` |
| 212 | |
| 213 | # make sure level zero dump exists; |
| 214 | # if it doesn't, start over |
| 215 | if [ "$firstlevel" != "0" ] ; then |
| 216 | # it doesn't matter if a previous dump exists from today |
| 217 | # since we're starting over as level 0 dump is missing |
| 218 | local dumped_today=false |
| 219 | local dumplevel=0 |
| 220 | rm -f $dumppath/*.gz |
| 221 | else |
| 222 | # otherwise just increment the dump level |
| 223 | # for levels 1-6, i.e. normally Tuesday thru Sunday |
| 224 | local dumplevel=`expr $lastlevel "+" 1` |
| 225 | fi |
| 226 | else |
| 227 | # no dump exists in this week's folder; reset level to '0' |
| 228 | local dumplevel=0 |
| 229 | fi |
| 230 | |
| 231 | # skip the entire dump process if a dumpfile has |
| 232 | # already been created for this filesystem today |
| 233 | if [ "$dumped_today" = "false" ] ; then |
| 234 | |
| 235 | # define the dump filename |
| 236 | local dumpfn=${DATE}_${dumplevel} |
| 237 | |
| 238 | echo ---------------- >> $LOGFILE |
| 239 | echo >> $LOGFILE |
| 240 | echo BEGINNING LEVEL $dumplevel DUMP OF \'$fsname\' \(${fspath}\) FILESYSTEM ON $HUMANDATE AT $HUMANTIME >> $LOGFILE |
| 241 | echo >> $LOGFILE |
| 242 | echo Creating a snapshot of \'$fspath\'.. >> $LOGFILE |
| 243 | # execute the dump |
| 244 | $DUMP -$dumplevel -$GLOBALDUMPOPTS -f ${dumppath}/${dumpfn} $fspath >> $LOGFILE 2>&1 |
| 245 | local dumpresult=$? |
| 246 | |
| 247 | if [ "$dumpresult" != "0" ] ; then |
| 248 | # log the dump result to syslog |
| 249 | $LOGGER "$DUMP LEVEL $dumplevel DUMP OF $fsname (${fspath}) FAILED!" |
| 250 | |
| 251 | echo "*** DUMP FAILED - LEVEL $dumplevel DUMP of $fsname (${fspath}) ***" >> $LOGFILE |
| 252 | echo >> $LOGFILE |
| 253 | else |
| 254 | # log the dump result to syslog |
| 255 | $LOGGER "LEVEL $dumplevel DUMP of $fsname (${fspath}) COMPLETED SUCCESSFULLY!" |
| 256 | |
| 257 | echo >> $LOGFILE |
| 258 | # compress the dump |
| 259 | echo Compressing the dumpfile \'${dumpfn}\'.. >> $LOGFILE |
| 260 | $GZIP -v ${dumppath}/${dumpfn} >> $LOGFILE 2>&1 |
| 261 | echo DONE >> $LOGFILE |
| 262 | echo >> $LOGFILE |
| 263 | |
| 264 | # make sure dumps are not world readable (security risk!) |
| 265 | echo Updating dumpfile \'${dumpfn}.gz\' permissions.. >> $LOGFILE |
| 266 | chmod -v -v 440 ${dumppath}/${dumpfn}.gz >> $LOGFILE 2>&1 |
| 267 | echo DONE >> $LOGFILE |
| 268 | echo >> $LOGFILE |
| 269 | |
| 270 | # reset current dump dir's timestamp to that of the level 0 dump |
| 271 | touch -t ${NEWEPOCHISO} ${dumppath} |
| 272 | |
| 273 | # delete old dumps |
| 274 | echo Deleting old \'$fsname\' dumpfiles.. >> $LOGFILE |
| 275 | find $BASEDIR/$fsname -mtime +$KEEPDUMPS -maxdepth 1 -print -exec rm -rf {} \; >> $LOGFILE 2>&1 |
| 276 | echo DONE >> $LOGFILE |
| 277 | echo >> $LOGFILE |
| 278 | fi |
| 279 | else |
| 280 | local lastdump_readable=`date -j -r $LASTDUMP +"%H:%M"` |
| 281 | local lastdump_readableZ=`date -j -r $LASTDUMP +"%Z"` |
| 282 | local lastdumpmsg="Autodump for filesystem '$fsname' ($fspath) has already been executed today at $lastdump_readable ($lastdump_readableZ)." |
| 283 | echo $lastdumpmsg |
| 284 | $LOGGER $lastdumpmsg |
| 285 | fi |
| 286 | } |
| 287 | |
| 288 | |
| 289 | # Dump filesystems defined in 'FSNAMES' |
| 290 | # |
| 291 | # Monday or Sunday (as selected by 'WEEKSTARTS') starts with |
| 292 | # the level 0 dump, with incrementals created through the rest of |
| 293 | # the week (autoincremented). If the level 0 dump is missing in |
| 294 | # the current week's folder for filesystem currently being backed |
| 295 | # up, it is created automatically instead of an incremental dump, |
| 296 | # no matter what day of the week it is. |
| 297 | for f in $FSNAMES |
| 298 | do |
| 299 | mk_auto_dump $f |
| 300 | done |
| 301 |
FreeBSD vs the world
Jun 22nd
As I upgraded few FreeBSD installations to FreeBSD 7.2 over the last couple of days, I took the customary stroll to see how FreeBSD continues to stack up against the Linux distributions. And once again I determined it does so very well. I’ve been a devout FreeBSD user for almost a decade, and every time I take a look at the Linux world I come back to the same conclusion: I like the fact that there is just one FreeBSD. It’s very well managed and its QA is excellent (not to mention its TCP stack is famed for being the most stable, and its ports collection rivals anything offered by Linux).
Here’re couple of useful sites for those wondering which OS to choose:
Polishlinux.org – Compare distros: FreeBSD vs. Debian – Comparison data is up to date and there are a lot of good user comments to sift through. You can also choose other distros to compare to.
Wikipedia – Comparison of BSD operating systems
And lastly, a good example of why the sheer number of Linux distros is disorienting: DistroWatch lists at least a few hundred Linux distros (plus couple of BSD derivatives).
Fusemail, strike one
May 3rd
Over last several weeks I’ve gradually externalized both my own and my employer’s mail systems from internal servers to an outsourced service. My own mail has been running for years on qmail on FreeBSD. It’s worked well, but the age of my own server has become a growing concern, and in general in event of a system failure mail would not flow – that’s not good, and nobody’s going to fix it if I’m out of town. So paying couple of bucks per month per mailbox is—at least in theory—worth it to not have to stress over mail system (even though I’ve found Postfix/Dovecot really interesting and actually quite pleasant to configure.. I was going to move the qmail system to Postfix before I started thinking about outsourcing the whole thing to save time).
Meanwhile, my employer’s email has been running on Exchange for several years, starting preceding my time with the company. It has been a grief, though I’m sure it’s partially due to the fact that the the mail server is also the domain controller of a small office LAN. But why should it be? Qmail or Postfix run quite well on a Linux/*BSD server with Apache, MySQL, BIND. So I’ve been looking forward getting rid of Exchange, and migrating to Postfix/Dovecot system until, again, I started thinking that perhaps it’s not worth the stress to run an internal mail server. I’m the only person tending to it and, say, if I’m on a vacation and the mail goes down, it would not be good.
Once I started considering outsourcing email an option, I started evaluating various services. Fusemail and Mailtrust quickly bubbled to the top. Fusemail has more features, and the deciding factors (in Fusemail’s favor) were the ability to adjust the spam filtering (Mailtrust only has “on” or “off” options which is a bit scary — if the filtering is too stringent or too lenient, there’d be nothing that could be done about it.. Mailtrust’s rep suggested that I might want to look into an external spam filtering solution if I wanted more control.. but no thanks; I had been running Katharion for mail filtering for several months which worked ok, but if I was going to outsource the mail, I wanted an integrated solution), and the ability to increase a mailbox allocation for an individual user by purchasing more user accounts and allocating their mailbox allowance to the existing users. Mailtrust is fixed to 10Gb.
On the web there is about 50/50 comments for and against the quality of support for both Fusemail and Mailtrust, so from the comments alone it was impossible to deduce which service would have better support. Pre-sales support was slightly better on Fusemail side, and the few quirks ran across during setup have been addressed satisfactorily.
Strike One
Tonight (Saturday evening) around 18:00 my user account under my employer’s master account suddenly disappeared. I access mail from Outlook via IMAP, and suddenly Outlook prompted for the account password. So I logged in to Fusemail admin account and clicked on my user name. [Paraphrasing] “Cannot edit terminated user account”. What?! To terminate a user account in Fusemail you have to check the checkbox next to the user name, click “Terminate”, check another checkbox (“yes, I’m sure I want to do that”), and then click on “Yes”. Only then does a user account get removed, or scheduled for deletion as it takes many, many hours for the username actually be purged from the system so that it can be taken into use again. I most certainly did not execute those steps. I’m the only one with access to that admin account, and the password is sufficiently complex so that it’s very unlikely the account would’ve been compromised. This leaves system error as the most likely cause. I called the emergency support around 18:30 and left a message (they claim to have someone on call), then again again around 20:00, and also opened an “Urgent” support ticket through their support system at 22:40. It’s now over six hours since my first “emergency” support request, so I can only assume the on-call person has gone to party (or that they don’t have an on-call tech in the first place). The emergency support number instructs the caller that “while the support technician is not immediately available, it does not mean that support would not be available immediately”. It’s looking like they were wrong.
I didn’t lose a tremendous amount of email (and perhaps Fusemail can restore it), but during this downtime emails to my account which has multiple “admin” aliases are being rejected. If I was running my own mail server I could obviously have fixed a problem already, but an outsourced solution is supposed to *reduce* system management stress.
Longevity of this outsourcing attempt depends largely on how Fusemail will deal with this situation. Having to reconfigure my user account and its associated aliases would be annoying, but more than restore I want to know what caused the problem, can they be sure to prevent it from recurring, and what’s the deal with the non-existent emergency support.
If the deleted account would’ve been that of the CEO of my employer, or my personal primary account (which I have also outsourced to Fusemail in a separate account), this first strike would’ve likely been also the last for Fusemail.
–
Couple of considerations for those who’re comparing, say, Fusemail and Mailtrust, or considering mail outsourcing in the first place:
- Forward/distribution management is currently better implemented in Mailtrust. It’s workable in Fusemail, but it’s more straightforward in Mailtrust. If this is an important feature to you, pay attention when you’re comparing the services.
- Secure connections (SMTP, IMAP, POP) work better with Mailtrust than with Fusemail. Fusemail is supposedly looking into this. Not a huge issue for me since the SMTP traffic is generally not encrypted anyway, so encrypting the last leg (from the service to the client) isn’t very significant.
- Fusemail’s IMAP is not blazingly fast even when accessed from a fast net connection. Same goes occasionally for their web client. They are, however, generally within acceptable limits.
- A general comment if you’re using SPF: when you use a service provider’s SMTP servers you can’t positively lock down who’s authorized to send mail for your domain. If someone who’s hosting their mail at Fusemail decides to send spam spoofing one of my domains, they’ll appear as authorized for the recipient’s spam filter since I’ve authorized Fusemail’s SMTP servers in my domains’ SPF records.
- Test (!) the support of different providers by sending them a support request on Saturday evening. See when you get a response. Fusemail claims on their website: “24x7x365 Support”, but I’m now finding that it is not completely solid; it should instead read: “You can leave us a message 24x7x365″.
- If you don’t have large number of users to support and they use IMAP to access the remote email, consider setting up backup mailboxes at gmail (free!), and creating a mail rule (available at least in Fusemail) which automatically copies those backup mailboxes for all inbound email.
Unix Shell: find files by a date range
Feb 23rd
I needed to restore some files from an archive on UNIX, but only the files of a particular date-range were needed. It took a few moments to find and figure out how I could easily extract files older than a particular date, or files from a particular date-range. This is how:
- Create a perimeter file, like so:
touch -t yyyymmddHHMM marker_date - List files older than the marker_date:
find . -type f ! -newer marker_date -ls
Of course, instead of `-ls’ parameter (to list), you can use `-print’ and a pipe to xargs to, for example, delete the selected files, etc.
Likewise, for a range of dates:
- Create the perimeter files:
touch -t yyyymmddHHMM range_start
touch -t yyyymmddHHMM range_end - List the files between the range dates:
find . -type f -newer range_start ! -newer range_end -ls