Different versions of shell commands like PHP, Vi – find the true location of Mac/Unix commands, aliases and links

Sometimes it can be a challenge to uncover what terminal command is actually being run on Mac / Unix / Linux systems. Over time, old aliases, links and the repeated installation, upgrading and removal of software can lead to existing and even untouched default commands either unable to be found or running a different version than expected.

Recently we have been using Homebrew to swap in and out multiple versions of PHP (5.4, 5.6, 7.1 etc.) on Macs. Whilst great for quickly testing and developing across versions, this makes it possible to have strange occurrences, like the $ which [command] returning a different version of the software to the one which the shell actually executes!

The following location mismatch demonstrates the problem:

# Problem: Command or Software (in this case php)
# Reported as missing or runs at different location


$ php -v
-bash: /usr/local/bin/php: No such file or directory


$ which php
/usr/bin/php


# WTF ???

Different locations are being referenced by $ which [command]  and the shell.

To fix the discrepancy, use the $ hash [command] to refresh the shell’s command location cache:

# Result before hash command
$ command -v
php /usr/local/bin/php

$ hash php
$

# Result after command
$ command -v php
/usr/bin/php

# Same version recognized everywhere
$ which php
/usr/bin/php

$ php -v
PHP 5.5.36 (cli) (built: May 29 2016 01:07:06)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2015 Zend Technologies

Great, order has returned to the universe and which is again pointing at the correct place. Keep in mind if you do replace (or re-link) the php at /usr/local/bin/php it will be executed instead of the /usr/bin/php, but now all commands should agree on the file’s location.

Debugging Aliases

The above situation can be particularly tricky when dealing with aliases.

If we define an alias and confirm it can be executed, the $ which [alias] and ls commands bizarrely return nothing! Where is the alias going? To find where and what the alias is actually running, utilise the $ type -a [command] command:

# Create alias and watch the confusing behavior
$ alias phpv='php -v'
phpv
PHP 5.5.36 (cli) (built: May 29 2016 01:07:06)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2015 Zend Technologies


$ which phpv
$


$ ls -l phpv
ls: phpv: No such file or directory


# The type command reveals all (-a)
$ type -a phpv
phpv is aliased to `php -v'

Debugging Links

Links act slightly different again. As discovered in this blog post, vi links to vim on a mac, however the which, type -a and command -v commands only shows the link name, not the target:

# These commands give information on links (ls -l is most useful)

$ which vi
/usr/bin/vi

$ type -a vi
vi is /usr/bin/vi

$ command -v vi
/usr/bin/vi

$ ls -l /usr/bin/vi
lrwxr-xr-x 1 root wheel 3 21 Aug 15:29 /usr/bin/vi -> vim

Here we can see that although ls -l was useless for aliases and commands, it is good for showing where links point to.

Although only a summary, these quick commands give a few pointers for when a command either cannot be found or a different version than expected is executing. If you’re still struggling to locate an executed command or know of other handy tips, please leave a comment.

Please share if you find our free website useful, it really helps us produce more tutorials!

Advertisements

Which Symfony Version number?

The Symfony console provides a -V option. This can be handy for quickly finding out which version of Symfony a system is running but it has moved location a bit over the years (note the uppercase -V or use –version):

$ php bin/console -V
Symfony version 3.1.2 - app/dev/debug

If this produces a bunch of errors about autoload.php then you need to run composer install to install other required parts of Symfony. Whilst if you receive a command not found error then try:

$ php app/console -V
Symfony version 2.7.10 - app/dev/debug

If still a command not found error then try:

$ php lib/vendor/symfony/data/bin/symfony -V
Symfony version 1.4.20

In all versions, running console without -V will produce a long list of all the commands available, along with the version info. This is very useful and really good regular learning exercise, the options really show how Symfony works.

As we can see, the console command moved to the project folder’s bin/ folder as of version 3.0 in Symfony2 versions the console command lived in the project’s app/ directory, whilst if only lib/vendor/symfony/data/bin/symfony exists then you’re using Symfony version 1 (now an obsolete legacy platform)!

Discovering on Mac OS X: vi -> vim

Ok, I admit it, I’ve only just now found out! Seems the vi terminal command on Mac OS X just points to vim anyway and always has done:

$ ls -l /usr/bin/vi
lrwxr-xr-x  1 root  wheel  3  9 Nov  2015 /usr/bin/vi -> vim

I started using a Mac as my main machine for software development in 2009 and have mostly used one since. Given the number of times I have typed a completely redundant m multiplied by the number of years I have been doing it for makes for some frightening numbers.

As a very quick and rough calculation, I made a quick Python doodle estimating how many times I probably opened vim everyday in each year (trying to judge how heavily I might have typed vim per day each year based on role and environment etc.), here here is basic estimation:

Kind of simplistic and assuming:

  1. Approximation of per day opening frequency
  2. Coding 235 full days a year
    (based on: work days + some weekend days + some evenings – holiday days)

This, depressingly, outputs:

237350 seconds

Which is a lot of redundant key strokes! Assuming I type the command at rate of 80 wpm, according to this website this is a kph (keystroke per hour rate) of around 20,000.

This, even more depressingly, equates to :

11.9 hours

The equivalent of a long day wasted …to add to the many I’ve encountered as a Software Developer.