September 07, 2017

Visual reminder for SSH'ing to production/staging etc servers

If you are anything like me, you have access to a ton of different servers and usually 10 sessions open at once.

If you are anything like me, you have experienced executing a command meant for a staging server on a production machine when under pressure.

The only problem was that when I made that error, that specific webserver was being used to give a presentation to the management and it broke the site...

June 29, 2016

Docker for OSX: Lotsa "wows", couple "ohws"

So I finally got the chance to experiment a bit with the new RC of docker for OSX.

July 17, 2015

How StackOverflow is encouraging laziness

First of all: this post is purely opinion based.
I have no hard evidence to stave my claims and they are based solely on my own observations over the years.

A bit of history...

Before the internet was available for everyone, developers were forced to figure out things on their own.  Sure there were bulletin boards, but one had to be able to access them.  Books as well, but you had to have money for those.  You could xerox some pages from a friend or colleagues' book if you knew someone. An ancient form of piracy!

If you were doing Pascal or Delphi at that time you could obtain a copy of SWAG (not what it means now! It stands for SourceWare Archive Group).  This was a downloadable, self-sustained library containing a huge amount of code snippets to help you with solving a lot of common issues.  The last version was from '97 (am I that old already?).

The SWAG was my personal bible for several years and I learned so much from it.
Thinking of it: I still have my Ralph Brown Interrupt List book laying around somewhere, clocking in at several kilograms.

Just to say that: We had to figure out things for ourselves.
You had to learn and practice a lot - which was good - but it slowed things down.
Everyone was forced to invent wheels and so on.

Let there be internet!

Then the internet came and it changed our lives.  Suddenly you had this vast and unlimited
resource of information.  And there were all these other people looking into the same thing and writing articles about them.  A miracle!

So awesome!
Wanted to know something? Ask Google, someone probably already did that or could at least help you.  You even had a couple specialised sites like Experts-Exchange.  If you knew how, you could always get to the answers without paying :o)

Then around 2010 I discovered StackOverflow and wow, what a joy.  Still practicing what I've learned all those years ago I turned to it often, but didn't feel the need to register or participate.
Eventually my competitive side caught up and I decided to jump in and register.

Even after that I've been more of a reader than a replier, so I didn't gain much reputation over the years.  But because I was spending more time on the site I started noticing some things.

Initially the biggest part of the questions were very challenging and about serious problems and so  on.  Sure there were the easier/starter questions, but they were posed only once (or quickly shut down with a duplicate label if not).

Over the course of the last years that changed.

I started to notice that questions became more trivial, stupid even.
Often they could be solved by a 3 second trip to Google or a glance at the documentation.
Also the number of repeat questions has been steadily going up.
For example: The last 2 months I've noticed a question about "Headers already sent" in PHP 5 or 6 times.


Thinking about this I realised that this whole reputation thing is a double edged sword.

Initially it drove people into participation.  Competitive behaviour has always been there and always will be.  It was simply the best solution to get the site going.

Fortunately the people answering questions back then were serious about providing the world with a great programming resource.  They were awesome in their answers and vigorous in their cleanup of junk questions.

With the big influx of new people - Everyone can program remember? - that has been changing.
Instead of flagging questions as duplicate (and thus trying to teach newcomers on how to correctly use the site) you had people jumping on the easy questions and answering them.
The question already had an accepted answer even before it could be flagged, all for that little gift that is more reputation.

This seems to result in lazier and lazier programmers in my opinion.
Well it's not just SO, I have noticed a big trend towards "doing as little as possible" the last couple of years, but still.

People come and ask one of those idiotic questions - something they could've solved themselves with about a minute of effort - and actually expect an answer and having their work done for them.
Not only that: Often after they get a reply they would continue asking more in the comments before handing out the accepted flag, mor than once unrelated to the original question.
I've witnessed a couple occasions where people answering were asked to write the entire piece of code.

The worst thing is, current responder behaviour on the site actually encourages this.  People do answer and do write that code.  We shouldn't be! We should be asking the OP things like:

  • What have you tried? 
  • Have you looked at your logs for an error message? 
  • Did you take a look at the documentation?
  • ...

Not provide them with an easy way out! That only encourages them the next time!

In my opinion the original purpose of Stack Overflow is about trying to educate your fellow developer.  Teach them, mold them, help them grow, guide them towards becoming a better developer.

Unfortunately it seems most people are thinking about their own reputation.
We are slowly losing the fight to laziness people, it's time to do something about that!


So... next time you see one of those questions:
Don't answer, help them discover a solution themselves by guiding them.
Don't go for the easy 15 points, as hard as that is.

And for those only wanting the reputation?
In my opinion there should be an "answered a lazy question" kind of penalty.
If your answer gets flagged for that 3 or more times you would lose double the reputation that you gained with it.

October 13, 2014

Shell scripts with admin privileges in Keyboard Maestro

I try to automate a lot of things using Keyboard Maestro and some things are accomplished using shell scripts. For example I have a couple macros that, when I arrive at a client, get triggered by a connect to their wireless network and set up routing, start some apps etc.

Now you probably know that modifying the routing table requires root privileges and if you trigger a shell script that requires SUDO the normal way, you get one of these:

Nice innit?

There are some messy ways we can solve this, like for example adding the script file name to the sudoers-file as a command that does not require a password. If you are like my, you won't like this approach. I really don't want to do this for each and every script I plan on adding.

The Solution

More like a solution. There are multiple paths here. I can't think of a way to have a console script popup a dialog on a Mac to get the password. Perhaps we could abuse some kind of mac-compatible ssh-askpass thing to accomplish this, but then you have the password and you'd still have to get the script to re-execute as root.. 

So, AppleScript perhaps? 

Since AppleScript can be interactive and you can tell it to run applications with administrator privileges, it seems like a good idea to just have some kind of sudo'ing script that triggers our shell script. 

Turns out this is a lot easier to do than expected:

Just fire up your applescript editor and type in this little thingy:

on run argv
   set script to (item 1 of argv)  
   do shell script script with administrator privileges
end run 

Save the script as sudo.scpt (or whatever you prefer)

So this little gem will actually popup a regular password dialog and then execute whatever shell script you specified as its first argument with admin privileges. In your shell script you just use sudo in front of your commands and it will work.

And in Keyboard Maestro?

Adding this to Keyboard Maestro is not that hard either. You can just use the "Execute Shell Script" action (not AppleScript!) as we will type in a full command line with arguments here. An AppleScript is ran by using osascript so that's what we start with:

And that's it basically. 
You can press the Try button. You'll get a password prompt and then your shell script will be triggered. Obviously you should modify everything to your needs.

Steve out.

October 06, 2014

MacOS and multiple (concurrent) Vagrant boxes

Are you running more than one Vagrant box concurrently, forcing you to resort to port numbers for correct working?

I am, and it's been annoying me for quite a while. Every of my sites has its own specific VirtualBox VM. Sometimes I might work on more than one at a given time (eg 2 sites communicating with each other via an API) so keeping them on the default ports and then only using 1 at a time wasn't a real solution.

So I decided to spend some time on the matter and see what I could trump up.
As it turns out... a lot!

April 02, 2013

HP K850 & F*ing expiring cartridge(s)

From joy...

A couple years ago I really needed an inktjet capable of printer A3 and preferably having separate cartridges for the colours. After some looking around I chose for the Hewlett Packard K850 with duplex module and network functionality. I was really happy about it and it server me well. A lot of paper went through that one...

... to hate!

Unfortunately I ran into some nasty stuff: Expiring cartridges. It seems that HP built in an enforced expiry date into the cartridges. And because I didn't use the inkjet enough to empty out cartridges I ran into this. Twice!

Now if you know what a standard HP cartridge costs, imagine having to buy 4 different onces. They go for about 40€ per piece in Belgium.

The first time this happened I wasn't very angry about it since they were almost empty. I looked for a solution, found none at first glance and decided to just replace them.

Unfortunately I do not use the printer as much anymore. So today I fired it up, printed a diagnostics page, did a head cleaning and then fired up my normal print-job. Imagine my anger when the stupid printer refused to print. I received the famous "Printer cartridge expired, please replace". Well, I wasn't going to replace 4 perfectly full cartridges, no matter how much HP whines about "aging ink and damaging your printer". The decision should always be the customers, not the manufacturer! It seems I also have one of the few models that does not allow the user to override this. *sigh*

and back to "joy".

So I started browsing the web. So many frustrated people with the same issue. I figured out that the driver sends the date to the printer using the "@PJL SET TIMESTAMP"-command. Knowing that on a Mac, the printer drivers can be found under /Library/Printers/, I opened up my Terminal and did an "ag" for TIMESTAMP in the /Library/Printers/hp/ folder. To my surprise I got 2 hits in a single file:


An XML, this must be my lucky day! Would HP be so careless as to store the entire communication protocol in an external file? 

This being a system file, I "sudo vi'ed" it and did a search. Both where "@PJL SET TIMESTAMP"-commands. So I just changed the TIMESTAMP into something else (in my case I simply replaced a letter with an X). After saving the file and rebooting (don't know if that is required), my printer is now happily spewing out pages again, with the "expired cartridges" as it has no idea anymore about what date it actually is. 

I decided however that I will not be buying new ink for this printer. When the cartridges are depleted I will get rid of the printer and never buy HP again. 

March 08, 2013

No explanation required...

I guess this needs no further explanation besides a "sigh":

switch ($month) {
case '01':
$maand = 'Januari';
case '02':
$maand = 'Februari';
case '03':
$maand = 'Maart';
case '04':
$maand = 'April';
case '05':
$maand = 'Mei';
case '06':
$maand = 'Juni';
case '07':
$maand = 'Juli';
case '08':
$maand = 'Augustus';
case '09':
$maand = 'September';
case '10':
$maand = 'Oktober';
case '11':
$maand = 'November';
case '12':
$maand = 'December';