Invest in your own health

Since I’ve been about 14 years old, I’ve been an entrepreneur.   I started mowing lawn, shoveling driveways and painting houses.  I bought a freaking office desk with my own money when I was 16 – ok I admit it that’s a bit weird.  I started writing software, in Pascal, on an Apple II+ in 1978.  I earned every penny to put myself through UMass/Amherst.  I became that legendary startup guy that worked 80+ hours.

Along the way, I lost track of the importance of eating right and exercising.  I was very aware of all the advice about taking care of yourself for all the right reasons.  I just never spent the time.  Until I was about 30, I completely got away with it – 5’9″ and 145 lbs – no matter what.  Then, 155 as soon as I turned 30, like it came in my birthday present – no big deal, 10 lbs.  As they say, onward and upward – working the long hours and on my way to 205 lbs by 50.  I wasn’t sleeping well, I spent several 3 to 4 days stints nursing a horrible back problem and my productivity was lower than years gone by.  I got really tired of feeling terrible and dragging ass all the time.

Starting in March, 2014 – no particular event or occasion – I started eating more reasonably, no crazy diet just smaller portions and better choices.  I also started going to the gym for an hour a day.  It was a big struggle to find an hour a day – how pathetic is that.  It was super boring too – headphones on an elliptical machine for a half hour and a half hour on some Nautilus equipment.  There were some strange mental wrestling matches about an hour a day, but in general, I stayed on track.  I lost the easy 15 lbs in the first 3 or four months and I started riding my bicycle in July of 2014.  The bicycle was far more interesting than the gym, so the rest of last summer was bit easier.  I still wasn’t convinced that I was committed, so I stuck with my 1985 Centurion LeMans RS 12 speed bicycle – that’s right, the 30 year old bike.  I used MapMyRide on my cellphone and my dashboard tells me that I rode about 600 miles that summer.  I went back to the boring gym over this past year’s record setting New England winter and weighted in at 170 lbs in March of 2015.

CycleBeing the geeky, data guy – I got a Garmin 810 GPS for my biking this summer.  It is awesome – it measures my heart rate, cycle cadence, power and mashes it up into a map overlay giving me all kinds of information about how I’m riding compared to previous rides and other cyclist in the area.  It also can track my ride live, so my wife can find out where I am along the ride.  I started riding in March, it was routinely 35 degrees and there wasn’t much daylight to squeeze in the rides.  My goal is to ride the same crappy bike 3000 miles before the cycling season ends – which is probably mid-November.  I’ve ridden approximately 2800 miles so far and here is some more data – 120 rides, 170 hours, 160,000 Calories burned with an average heart rate of 85% of the max.  Still 5′,9″ but now 155 lbs which is a loss of 50 lbs in the past 18 months.

So 170 hours was the hardest part, I’m still the crazy busy startup guy with a family and several other obligations and activities.  During these rides, I get to think about many things – a huge benefit to get away, uninterrupted.  I’ve thought about making this investment, not only for myself but for family, friend and my business.  I’ve done the math on the time against my typical work week and I believe I’ve cut my hours by approximately 10% over this past cycle season.  I’m certain that I’m in a totally better situation – I sleep far better, I have zero back issues, I enjoyed snowboarding all last winter, I’m awake and alert all day and far more productive throughout the entire day.  I’m certain that I’ve got far more than a 10% return on this time, not to mention the other benefits.  I’m not looking forward to going back to gym, I might try compu-cycling and use my rowing machine.

In any case, I’m thrilled that something happened and I changed my situation – it was worth it.

What this CTO does.

The role of a CTO is a topic that inspires many to ask so many questions.  What is the difference between a CTO and a VP of Engineering?  What to look for in a startup CTO?  There are literally hundreds of posts on the topic and deep comments threads explaining various experiences in various scenarios.  I think that is exactly the take away; the specific scenario matters.  The specifics being important and not unique to the CTO role.  A good sales leader in one business doesn’t necessarily work in all the other businesses.

My experience as a CTO has been in the area of building native cloud based, highly scalable platforms from the ground up.  The platforms have been built to process massive amounts of data, high transaction volumes and large numbers of concurrent users or device interactions.  When I say from the ground up, I mean that I run around with powerpoint slides and wireframes describing the business before a line of code is written.  The first goal is alway to sanity check the business idea.  The idea always changes, often in big ways (aka. the infamous “pivot”) – so it most likely is a total waste of time and money to write code to aid in describing the business value.  I’ve raised at least $20M with PPT and zero code.  Yet, I’m literally contacted two times a week by folks that want help or advice in writing prototype code so they can raise money.  What?  You might be talking with the wrong folks if they need a prototype or maybe you are not explaining your idea clearly.

Unfortunately, I don’t get to write code these days.  I’ve read all the comments about if the CTO doesn’t write code then go get someone else.  That advice is total baloney.  What is much more likely to be true is that an architect or lead developer is needed for that particular business and you should not being describing the role as CTO.

So what do I do as a CTO?  Thinking back over the past companies that I’ve been a CTO, I spend a lot of time translating business ideas to a platform concept or dear I say, vision.  I also spend time researching available technology to support the future platform architecture – I refuse to build things that already exist, I want to concentrate on building the new, non-existent stuff as quickly as possible.  I also spend time reverse translating platform capabilities to business use cases – in other words, how does the technology support solving the important business problem – in the end, that is the entire point.

I’m deeply involved in contract negotiations, especially in relationships that involve critical technology partners.  There are many important aspects of technology partnerships that will cto-areas-of-responsibilitymake or break the value of your platform as an asset and in turn, maybe even your entire business model.  For example, data rights and protection of intellectual property are critical.  Similarly, I spend a lot of time in helping sales and business development understand customer use cases and mapping it to our platform, or in identifying creative ways to fill gaps or in recognizing a general pattern that needs to be built into our platform.

I’ve been part of businesses that have raised hundreds of millions of dollars and have sold several of these businesses.  I spend a lot of time in the due diligence process – explaining our platform inside and out, describing our discipline and investments, forecasting future ideas and in general supporting the idea that we have a technology asset that is truly worth something and supports our business idea.

I’m responsible for recognizing intellectual property and doing something about it.  Notice that I’m not just leaving it as, filing a patent.  That is because filing a patent is just one small thing that you do to protect your IP; quite honestly, probably not the most important.  I believe that if you have something that is true IP, that you need to get it to market quickly and run with it as fast as possible because that is what makes it really defendable and it often is the key business differentiator that every business wants to include in their pitch.

I spend a good amount of time identifying and understanding emerging technology and trends.  I look for opportunities to use or integrate in support of solving problems or filling gaps; I’m also interested in potential threats or disruptors.

Finally, just beyond the first couple of weeks and months, there is a ton of team work investments and operational stuff that I need to make and this grows with the size of the business.  Having bought and sold a few business, I understand how companies evaluate a technology based business and what value is assigned upon acquisition but also how companies forecast future investment requirements.  In other words, buying a great technology idea running in my basement with no documentation run by cowboys is far less valuable than a well documented platform, running in a fault tolerant architecture cared for by a top-notch team of professionals with verifiable workflows.  Building that isn’t free, but well worth paying those investment taxes along the way.

See no code, sadly for me – but then, I’m not the lead developer or architect or even the engineering manager.


Avoid email bankruptcy

Email is useful but can be evil if you let it manage you.  Friends and colleagues often tell me that they are overrun by email, missing important communications and failing to execute.  I’ve even seen people declare email bankruptcy where they’ve lost control and stop trying to “keep up”.  My inbox has exactly one message in it as I write this post.emailInbox  I get plenty of email – Google lets me know that I have approximately 10G / year.  Below are some of the ways that I avoid email bankruptcy and have a reasonable relationship with email.

I read email 2 times per day, one time first thing in the morning and one time at the end of the day for a total of 1 hour per day.  Email is for asynchronous communications – in other words, things that can wait until the reader gets a chance to read it on their schedule; it is not 911.  There are plenty of better tools for simple, quick back and forth communications – txt, twitter, Skype, etc…  It isn’t my problem if folks don’t understand what email is for and how to use it.  But it becomes my problem if I train folks that I’m on email all the time and I will reply back in 1 minute.

When I do read email, I avoid the practice of skimming with an intent to spend more time on it later.  I think that it is important to understand context as well as message content, a re-read forces you to re-invest in both.

I don’t use email as my task list.  Currently, I’m using Producteev as my task list – works across all devices and does all the good stuff that I like – tag, schedule, subtask, share, assign to others, follow, note, etc.  So, when I’m reading email that includes something that I think I need to attend to, I create a task in my task list with everything that I need from the email – attachments, dates and other important information – and archive the email.  I literally do not need the email any more.

I don’t sort email.  I use to sort email, but two things dawned on me.  First, I had to come up with a fixed and static organization to sort message into.  I tried sorting by sender, by topic, by importance, etc…  As things changed for me over time, I was constantly adjusting and re-sorting.  It also occurred to me that I was spending time on preparing for a search that may never come.  At about the time that I cut over from Outlook to just using native Gmail, I started just archiving – no use of tags to simulate folders.  If and when I need to find something, I just use the built in search.  Admittedly, ever once in a blue moon, I have to spend some time in the advanced search criteria trying to remember approximately when a message occurred, looking for attachments, guessing at words that may have been included in the message.  But I always find what I am looking for and I’m totally confident that if I added up all the time that I spend on actual searches, it is far, far less than the cost of sort and resorting.

I make extensive use of Gmail filters and automation.  If you spam me, I mark the message as spam and Gmail does a decent job of not showing me any more messages from you.  If you spam me again, referring to the earlier spam that you sent me, I mark the message as spam and I call you a name.  I’m an active “un-subscriber” – meaning, I do not just let some service continuously send updates that I’m not interested in – I just cut the cord.  Finally, I make extensive use of filters to bypass my inbox and go directly to archive when email is routine status updates and system type message that are good to have as references but I don’t need to waste time reading or managing messages about all systems being healthy.

I use Boomerang to help me follow up on communications that might otherwise go into a blackhole.  I don’t need to create a task to follow up with so-and-so when I send an email asking someone to do something.  In most cases, my team automatically knows to follow up with me, but Boomerang helps me remember without having to keep the message in my inbox as my reminder system.

Service Platforms not Product

For some time now, technology appears to be trending away from selling products and towards selling products as a service.  Netflix lets you stream all the movies you want, Amazon delivers all the books you want.  Movies and books are migrating from nouns to verbs. 5fc2ba31a62a343 Amazon has migrated from a product to a platform for selling products and they are selling services that they did not create.  Apple, Microsoft, Facebook and Google all have platforms that enable others to build services.  API are extensive so that ecosystems can evolve and support various businesses – even competitors.  Trying to build all the services in an ecosystem or network doesn’t scale, so you must build an open platform. Heck, at Linkable Networks, I’ve been building an open platform that changes printed coupons to digital coupons and enables partners to build their loyalty platform using my API.

The consumer side of this is that product ownership is migrating to access.  Consumer’s don’t need email servers anymore, we use email as a service.  We subscribe to cable and cell services.  We’re quickly heading towards not owning any movies, books and music.  ZipCar has pioneered transportation as a service.  AirBnB is offering hotel as a service.  How much longer before education, games and many other things are delivered as services?

Beyond the MVP

One of the most important product management concepts is getting to market sooner rather than later with the Minimally Valuable Product (MVP) and iterating or pivoting as you gather feedback and learn, especially if you are building new, innovative products.  This is simply the 80/20 rule applied to product management.  Ignoring this concept and you risk over investing before you truly understand market requirements and you are very unlikely to get a return on your time and money.

MinimumViableProductBut what happens after you’ve validated that your MVP is on-track and valuable?  How do you decide how much of the remaining 20% improvement is worth your time and money?  Information is the missing ingredient and often it doesn’t exist when you’re building something new.  The Imitation Game movie is about how Alan Turing crack the enigma code by building what many folks believe is the first computer.  The key was reducing the breadth of the problem, reducing it again and finally searching for a pattern to build into your product.  You can always expand the scope later.

How do you get the non-existent information?  In years past, the only way to get non-existent data is to gather the information yourself – often this is slow and very expensive.  All the map product guys employ many people to drive around and gather information on roads and buildings.  Startups never have the resources that Google has so alternatively today, crowdsourcing is an outstanding method and alternative to gathering your own data.  For example, Waze designed a product that encouraged their users to provide feedback and they crowdsourced information that would have cost many millions of dollars.

Finally, when you’re in the trenches of reducing the problem scope and searching for patterns, be on the lookout for technology game changers – i.e. internet, mobile, cloud, etc. – that change assumption and unlock new pathways.

You know why I’m here

Just some blogging fun here…

In the world’s biggest noise factory, the SuperBowl, Marshawn Lynch continues to straight arm the circus performers as he responds to every question with “You know why I’m here”. He defies the NFL’s mandates, wearing his unapproved beast mode gear while trending on twitter. Genius media stunt or pampered starred athlete who is breaking his contract? Marshawn Lynch
Meanwhile, “All-Pro Stanford Graduate”, Richard Sherman attempts to redirect the mob to more important matters. Mission accomplished, I’m entertained by the entertainment (and remember, sports entertainment is the NFL’s business) and I will survive without the philosophical gems laid down by NFL players.

I will admit that I like the phase “You know why I’m here”; it got me thinking. Not about checking the box, conforming to the rules, avoiding the penalty – but about strongly believing in something and sticking to it. Cutting through the noise, facing adversity and staying on a mission is difficult and when you take this path, you’ll stand out which will make it even more difficult. I see many examples of following the pack, getting into a routine, doing the comfortable stuff – all ok, not bad. You definitely need to take care of some basics, but remembering why you are here and pushing is super important.

Full disclosure, I’m a Patriots fan.  Patriots 30, Hawks 20.

Go Patriots!

Now I have to go find a t-shirt with this quote.

My Bash Profile

In the past couple of weeks, several folks have asked me to share my bash profile.  I’m not sure why, maybe better bash profiles are high on everyone’s new year’s resolutions.🙂 This post should also give my daughter a good chuckle and reassure her that I’m still a geek.

In any case, these days I mostly work with Macs and Ubuntu AWS instances and the bash profiles are a bit different.  I’ll document my Mac profile, I’m sure you can tweak to your OS.

Finally, these are the configurations that I have found personally useful in my work. I’ve accumulated this profile from many folks that I’ve worked with and several online resources – sorry if I’m not properly giving full attribution, I assure you nearly none of these configurations have come from my own thinking.


# -------------------------------------------------------------------
# Description: This file holds all my BASH configurations and aliases
# Sections:
# 1. Include other sources
# 2. Environment Configuration
# 3. File and Folder Management
# 4. Searching
# 5. Process Management
# 6. Networking
# 7. System Operations & Information
# 8. Development
# --------------------------------------------------------------------

# --------------------------------
# 1. Include other sources
# --------------------------------

# Source any base profile
[[ -s "$HOME/.profile" ]] && source "$HOME/.profile" # Load the default .profile

# Source Bash base aliases
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases

# -------------------------------
# -------------------------------

# Change Prompt
# ------------------------------------------------------------
export PS1="______________________________\n| \w @ \h (\u) \n| => "
export PS2="| => "

# Set Default Editor
# ------------------------------------------------------------
export EDITOR=/usr/bin/vi
export SVN_EDITOR=vi

# Set default blocksize for ls, df, du
# from this:
# ------------------------------------------------------------
export BLOCKSIZE=1k

# ------------------------------------------------------------
export GREP_OPTIONS='-D skip --binary-files=without-match --ignore-case'

# Maven
# ------------------------------------------------------------

export M2_HOME=/usr/local/maven
export M2=$M2_HOME/bin

# ------------------------------------------------------------
export MYSQL_HOME=/usr/local/mysql

# ignore .svn in filename completion
# ------------------------------------------------------------
export FIGNORE=.svn

# ------------------------------------------------------------
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home

# EC2 Tools
# ------------------------------------------------------------
export EC2_HOME=/usr/local/ec2

# EC2 Chip's Environment
# ------------------------------------------------------------
export AWS_ACCESS_KEY="yourkeyhere"
export AWS_SECRET_KEY="yoursecrethere"
export EC2_CERT=~/.ssh/yourcerthere.pem
export EC2_PRIVATE_KEY=~/.ssh/yourkeyhere.pem

# My Scripts
# ------------------------------------------------------------
export SCRIPT_HOME=/usr/local/scripts

# ------------------------------------------------------------
set -o vi

# Set Paths
# ------------------------------------------------------------
export PATH=".:$PATH:/usr/local/sbin:/usr/local/mysql/bin:$M2:$EC2_HOME/bin:$SCRIPT_HOME"

# Command configs
# -----------------------------
alias cp='cp -iv' # Preferred 'cp' implementation
alias mv='mv -iv' # Preferred 'mv' implementation
alias mkdir='mkdir -pv' # Preferred 'mkdir' implementation
alias ll='ls -FGlAhp' # Preferred 'ls' implementation
alias less='less -FSRXc' # Preferred 'less' implementation

# ls family
# ------------------------------------------------------------
alias ls='ls -la' # Standard
alias lx='ls -lXB' # Sort by extension.
alias lk='ls -lSr' # Sort by size, biggest last.
alias lt='ls -ltr' # Sort by date, most recent last.
alias lc='ls -ltcr' # Sort by/show change time,most recent last.
alias lu='ls -ltur' # Sort by/show access time,most recent last.

# cd family
# ------------------------------------------------------------
cd() { builtin cd "$@"; ll; } # Always list directory contents upon 'cd'
alias cd..='cd ../' # Go back 1 directory level (for fast typers)
alias ..='cd ../' # Go back 1 directory level
alias ...='cd ../../' # Go back 2 directory levels
alias .3='cd ../../../' # Go back 3 directory levels
alias .4='cd ../../../../' # Go back 4 directory levels
alias .5='cd ../../../../../' # Go back 5 directory levels
alias .6='cd ../../../../../../' # Go back 6 directory levels
alias ~="cd ~" # ~: Go Home

# misc
# ------------------------------------------------------------
alias f='open -a Finder ./' # f: Opens current directory in MacOS Finder
alias c='clear' # c: Clear terminal display
alias ducks='du -cks *|sort -rn|head -11' # ducks: List top ten largest files/directories in current directory
alias which='type -all' # which: Find executables
alias path='echo -e ${PATH//:/\\n}' # path: Echo all executable Paths
alias showOptions='shopt' # showOptions: display bash options settings
alias fixStty='stty sane' # fixStty: Restore terminal settings when screwed up
alias cic='set completion-ignore-case On' # cic: Make tab-completion case-insensitive
mcd () { mkdir -p "$1" && cd "$1"; } # mcd: Makes new Dir and jumps inside
trash () { command mv "$@" ~/.Trash ; } # trash: Moves a file to the MacOS trash
ql () { qlmanage -p "$*" >& /dev/null; } # ql: Opens any file in MacOS Quicklook Preview
alias DT='tee ~/Desktop/terminalOut.txt' # DT: Pipe content to file on MacOS Desktop

# lr: Full Recursive Directory Listing
# ------------------------------------------
alias lr='ls -R | grep ":$" | sed -e '\''s/:$//'\'' -e '\''s/[^-][^\/]*\//--/g'\'' -e '\''s/^/ /'\'' -e '\''s/-/|/'\'' | less'

# mans: Search manpage given in argument '1' for term given in argument '2' (case insensitive)
# displays paginated result with colored search terms and two lines surrounding each hit.
# Example: mans mplayer codec
# --------------------------------------------------------------------
mans () {
man $1 | grep -iC2 --color=always $2 | less

# showa: to remind yourself of an alias (given some part of it)
# ------------------------------------------------------------
showa () { /usr/bin/grep --color=always -i -a1 $@ ~/Library/init/bash/aliases.bash | grep -v '^\s*$' | less -FSRXc ; }

# -------------------------------
# -------------------------------
zipf () { zip -r "$1".zip "$1" ; } # zipf: To create a ZIP archive of a folder
alias numFiles='echo $(ls -1 | wc -l)' # numFiles: Count of non-hidden files in current dir
alias make1mb='mkfile 1m ./1MB.dat' # make1mb: Creates a file of 1mb size (all zeros)
alias make5mb='mkfile 5m ./5MB.dat' # make5mb: Creates a file of 5mb size (all zeros)
alias make10mb='mkfile 10m ./10MB.dat' # make10mb: Creates a file of 10mb size (all zeros)

# cdf: 'Cd's to frontmost window of MacOS Finder
# ------------------------------------------------------
cdf () {
currFolderPath=$( /usr/bin/osascript <<EOT
tell application "Finder"
set currFolder to (folder of the front window as alias)
on error
set currFolder to (path to desktop folder as alias)
end try
POSIX path of currFolder
end tell
echo "cd to \"$currFolderPath\""
cd "$currFolderPath"

# extract: Extract most know archives with one command
# ---------------------------------------------------------
extract () {
if [ -f $1 ] ; then
case $1 in
*.tar.bz2) tar xjf $1 ;;
*.tar.gz) tar xzf $1 ;;
*.bz2) bunzip2 $1 ;;
*.rar) unrar e $1 ;;
*.gz) gunzip $1 ;;
*.tar) tar xf $1 ;;
*.tbz2) tar xjf $1 ;;
*.tgz) tar xzf $1 ;;
*.zip) unzip $1 ;;
*.Z) uncompress $1 ;;
*.7z) 7z x $1 ;;
*) echo "'$1' cannot be extracted via extract()" ;;
echo "'$1' is not a valid file"

# ---------------------------
# ---------------------------

alias qfind="find . -name " # qfind: Quickly search for file
ff () { /usr/bin/find . -name "$@" ; } # ff: Find file under the current directory
ffs () { /usr/bin/find . -name "$@"'*' ; } # ffs: Find file whose name starts with a given string
ffe () { /usr/bin/find . -name '*'"$@" ; } # ffe: Find file whose name ends with a given string
ft() { /usr/bin/find . -name "$2" -exec grep -il "$1" {} \;
} # ft: Find text in any file

# spotlight: Search for a file using MacOS Spotlight's metadata
# -----------------------------------------------------------
spotlight () { mdfind "kMDItemDisplayName == '$@'wc"; }

# ---------------------------
# ---------------------------

# findPid: find out the pid of a specified process
# -----------------------------------------------------
# Note that the command name can be specified via a regex
# E.g. findPid '/d$/' finds pids of all processes with names ending in 'd'
# Without the 'sudo' it will only find processes of the current user
# -----------------------------------------------------
findPid () { lsof -t -c "$@" ; }

# memHogsTop, memHogsPs: Find memory hogs
# -----------------------------------------------------
alias memHogsTop='top -l 1 -o rsize | head -20'
alias memHogsPs='ps wwaxm -o pid,stat,vsize,rss,time,command | head -10'

# cpuHogs: Find CPU hogs
# -----------------------------------------------------
alias cpuHogs='ps wwaxr -o pid,stat,%cpu,time,command | head -10'

# topForever: Continual 'top' listing (every 10 seconds)
# -----------------------------------------------------
alias topForever='top -l 9999999 -s 10 -o cpu'

# ttop: Recommended 'top' invocation to minimize resources
# ------------------------------------------------------------
# Taken from this macosxhints article
# ------------------------------------------------------------
alias ttop="top -R -F -s 10 -o rsize"

# myPs: List processes owned by my user:
# ------------------------------------------------------------
myPs() { ps $@ -u $USER -o pid,%cpu,%mem,start,time,bsdtime,command ; }

# tm: Search for a process
# ------------------------------------------------------------
alias tm="ps -ef | grep"

# ---------------------------
# ---------------------------

alias myIP='curl' # myIP: Public facing IP Address
alias netCons='lsof -i' # netCons: Show all open TCP/IP sockets
alias flushDNS='dscacheutil -flushcache' # flushDNS: Flush out the DNS Cache
alias lsock='sudo /usr/sbin/lsof -i -P' # lsock: Display open sockets
alias lsockU='sudo /usr/sbin/lsof -nP | grep UDP' # lsockU: Display only open UDP sockets
alias lsockT='sudo /usr/sbin/lsof -nP | grep TCP' # lsockT: Display only open TCP sockets
alias ipInfo0='ipconfig getpacket en0' # ipInfo0: Get info on connections for en0
alias ipInfo1='ipconfig getpacket en1' # ipInfo1: Get info on connections for en1
alias openPorts='sudo lsof -i | grep LISTEN' # openPorts: All listening connections
alias showBlocked='sudo ipfw list' # showBlocked: All ipfw rules inc/ blocked IPs

# ii: display useful host related information
# -------------------------------------------------------------------
ii() {
echo -e "\nYou are logged on ${RED}$HOST"
echo -e "\nAdditionnal information:$NC " ; uname -a
echo -e "\n${RED}Users logged on:$NC " ; w -h
echo -e "\n${RED}Current date :$NC " ; date
echo -e "\n${RED}Machine stats :$NC " ; uptime
echo -e "\n${RED}Current network location :$NC " ; scselect
echo -e "\n${RED}Public facing IP Address :$NC " ;myip
#echo -e "\n${RED}DNS Configuration:$NC " ; scutil --dns

# ---------------------------------------
# ---------------------------------------

# cleanupDS: Recursively delete .DS_Store files
# -------------------------------------------------------------------
alias cleanupDS="find . -type f -name '*.DS_Store' -ls -delete"

# finderShowHidden: Show hidden files in Finder
# finderHideHidden: Hide hidden files in Finder
# -------------------------------------------------------------------
alias finderShowHidden='defaults write ShowAllFiles TRUE'
alias finderHideHidden='defaults write ShowAllFiles FALSE'

# cleanupLS: Clean up LaunchServices to remove duplicates in the "Open With" menu
# -----------------------------------------------------------------------------------
alias cleanupLS="/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -kill -r -domain local -domain system -domain user && killall Finder"

# screensaverDesktop: Run a screensaver on the Desktop
# -----------------------------------------------------------------------------------
alias screensaverDesktop='/System/Library/Frameworks/ScreenSaver.framework/Resources/ -background'

# freq: Which commands do you use the most
# -----------------------------------------
alias freq='cut -f1 -d" " ~/.bash_history | sort | uniq -c | sort -nr | head -n 30'

# CMDFU lookup
cmdfu(){ curl "$@/$(echo -n $@ | openssl base64)/plaintext"; }

# easily scp a file back to the host you are connecting from and place on Desktop
mecp () { scp "$@" ${SSH_CLIENT%% *}:Desktop/; }

# ---------------------------------------
# ---------------------------------------
alias aEdit='sudo edit /etc/apache2/httpd.conf' # aEdit: Edit httpd.conf
alias aLogs="less +F /var/log/apache2/error.log" # aLogs: Shows apache errorlogs
alias aRestart='sudo apachectl graceful' # aRestart: Restart Apache
alias aTail='tail -n 1000 -f /var/log/apache2/error.log /var/log/apache2/access.log' # aTail: Tails HTTP error logs

alias hEdit='sudo edit /etc/hosts' # hEdit: Edit /etc/hosts file
httpHeaders () { /usr/bin/curl -I -L $@ ; } # httpHeaders: Grabs headers from web page

# httpDebug: Download a web page and show info on what took time
# -------------------------------------------------------------------
httpDebug () { /usr/bin/curl $@ -o /dev/null -w "dns: %{time_namelookup} connect: %{time_connect} pretransfer: %{time_pretransfer} starttransfer: %{time_starttransfer} total: %{time_total}\n" ; }

# AWS EC2 Functions
# ---------------------------------------
# Instance id info: pull the 2nd field which is instance id from ec2 info
ec2id() { ec2-describe-instances -H --filter tag:Name="$1"|grep -i instance | awk '/INSTANCE/{print $2}'; }

#ec2elip() { ec2-describe-instances -H --filter tag:Name="$1"|grep -i instance | awk '/INSTANCE/{print $2}'|ec2-describe-addresses --filter=instance-id= -; }
# grabs instance id from lookup and passes it to find associated elastic ips

ec2elip() { local awsid=`ec2-describe-instances -H --filter tag:Name="$1"|grep -i instance | awk '/INSTANCE/{print $2}'`; echo $awsid; ec2-describe-addresses -F instance-id="$awsid"; }
ec2info() { ec2-describe-instances -H --filter tag:Name="$1"; };

# awk or cut -f 3 would work
ec2volinfo() { ec2-describe-instances -H --filter tag:Name="$1"|grep -i vol | awk '/BLOCKDEVICE/{print $3}' | ec2-describe-volumes -;}
ec2volsnap() { ec2-create-snapshot "$1" "$2"; } # use ec2volinfo first to get vol id

# IP Address info: pull the 4th field which is ip address from ec2 info
ec2ip() { ec2-describe-instances -H --filter tag:Name="$1" |grep -i instance | awk '/INSTANCE/{print $4}'; }