Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bash: "which adb" returns nothing, but "command -v adb" returns what i'd expect

This is a bash weirdness that's been bugging me.

I'm on OSX.

I've installed the android SDK, and as a result the adb tool is located in a folder in my home directory. That folder appears in my path as reported by env as ~/Development/android_sdk_latest/platform-tools.

adb itself runs just fine, but when I do which adb the result is empty. If I do command -v adb, the result is the full path, as expected: /Users/me/Development/android_sdk_latest/platform-tools/adb

adb does not appear in my aliases.

What subtlety of bash paths or which am I in the dark on?

like image 740
orion elenzil Avatar asked Jun 01 '16 22:06

orion elenzil


1 Answers

You've run into a subtle incompatibility between /bin/bash and the which command.

On my system (Linux Mint), the which command is actually a shell script, not a built-in command, and its first line is #! /bin/sh. That means that it uses /bin/sh's handling of the $PATH variable.

This can vary depending on how /bin/sh is set up (it's sometimes a symlink to /bin/bash), but a little experimentation shows that bash handles a literal ~ character in $PATH as if it were the full path to your home directory, but /bin/sh does not. Since you have

~/Development/android_sdk_latest/platform-tools

as one of the elements of your $PATH, bash (your interactive shell) can find the adb command, but sh (the shell used by which) cannot.

On some systems, apparently including your OSX system, which is a binary executable. Again, since it's not a bash script, it's not going to match bash's treatment of $PATH.

I recommend making two changes.

First, don't put a literal ~ in your $PATH. For example, to append the platform-tools directory to your $PATH, rather than this:

export PATH="$PATH:~/Development/android_sdk_latest/platform-tools" # BAD!

do this:

export PATH="$PATH:$HOME/Development/android_sdk_latest/platform-tools"

The $HOME will expand to the path to your home directory (when you run the export command, not when you use $PATH later). ~ is not expanded within double-quoted strings.

Second, rather than using the which command, use the type command that's built into bash. type will follow the rules of your current shell rather than those of /bin/sh, and it will be able to report shell functions and aliases that which is unable to see. It has several useful command-line options; type help type at a bash prompt for details.

The bash shell's treatement of ~ characters in $PATH is documented in the bash manual's section on Tilde Expansion.

like image 82
Keith Thompson Avatar answered Sep 22 '22 12:09

Keith Thompson