Any sufficiently advanced magic is indistinguishable from technology.
| Bash Reference Manual | ||
|---|---|---|
| 3.2.1 | Simple Commands | |
| 3.7.2 | Command Search and Execution | |
| 4.2 | Builtin Commands | |
| 3.3 | Shell Functions | |
| 6.6 | Aliases | (What 3.7.2 did not tell you.) |
TL;DRNAME [OPTION]...
|
||
NAME
which - locate a command
--read-alias, -i
Read aliases from stdin, reporting matching ones on stdout. This is
useful in combination with using an alias for which itself. For
example:
alias which='alias | which -i'
--read-functions
Read shell function definitions from stdin, reporting matching ones
on stdout. This is useful in combination with using a shell func-
tion for which itself. For example:
which() { declare -f | which --read-functions $@ }
export -f which
--version, -V
Print version information on standard output.
|
$ | which which |
|---|---|
| /usr/bin/which | |
$ | which -a which |
| /usr/bin/which /bin/which | |
$ | which -a which | xargs stat -c %N |
| '/usr/bin/which' -> '/bin/which' '/bin/which' |
$ | printf 'Hello %s\n' 'Mr. Bond' | |
|---|---|---|
| Hello Mr. Bond | ||
$ | printf -v greeting 'Hello %s\n' James | |
| $ | echo $greeting | |
| Hello James | ||
$ | which printf | |
| /usr/bin/printf | ||
$ | /usr/bin/printf -v greeting Aloha ; echo '$?'=$? greeting=$greeting | # WTF moment |
| -v/usr/bin/printf: warning: ignoring excess arguments, starting with ‘greeting’
$?=0 greeting=Hello James |
$ | builtin printf -v greeting Aloha ; echo '$?'=$? greeting=$greeting |
|---|---|
| $?=0 greeting=Aloha | |
$ | builtin printf || echo '$?'=$? |
| printf: usage: printf [-v var] format [arguments]
$?=2 | |
$ | builtin which || echo '$?'=$? |
| bash: builtin: which: not a shell builtin
$?=1 |
$ | function printf { echo -n function:\ ; builtin printf "$@"; } |
|---|---|
| $ | printf 'Hello %s\n' Michael |
| function: Hello Michael | |
$ | which printf |
| /usr/bin/printf | |
$ | declare -f printf || echo '$?'=$? |
printf ()
{
echo -n function:\ ;
builtin printf "$@"
} | |
$ | declare -f which || echo '$?'=$? |
| $?=1 |
$ | alias printf='echo -n alias:\ ; printf' | |
|---|---|---|
| $ | printf 'Hello %s\n' Michael | # WTF moment |
| alias: function: Hello Michael | ||
$ | alias printf='echo -n alias:\ ; /usr/bin/printf' | |
| $ | printf 'Hello %s\n' Michael | |
| alias: Hello Michael | ||
$ | which printf | |
| /usr/bin/printf | ||
$ | alias printf || echo '$?'=$? | |
| alias printf='echo -n alias:\ ; /usr/bin/printf' | ||
$ | alias which || echo '$?'=$? | |
| bash: alias: which: not found
$?=1 |
$ | function which { # Success !~}>
local _fmt=%n _opt='' _all=continue _cmd
case "$1" in
-a) _fmt=%N _opt=-a _all=true; shift ;;
-*) \builtin printf 'Illegal option %s\nUsage: which [-a] args\n' "$1"; return 2 ;;
esac
for _cmd in "$@"; do
\builtin alias "$_cmd" 2>/dev/null && $_all
\builtin declare -f "$_cmd" && $_all
\builtin "$_cmd" &>/dev/null ; [ $? -ne 1 ] && echo builtin $_cmd && $_all
env which $_opt "$_cmd" | xargs stat -c $_fmt
done } | |
|---|---|---|
$ | function which { # A longer but cleaner implementation
local _fmt=%n _opt='' _cmd _type
case "$1" in
-a) _fmt=%N _opt=-a; shift ;;
-*) \builtin printf 'Illegal option %s\nUsage: which [-a] args\n' "$1"; return 2 ;;
esac
for _cmd in "$@"; do
for _type in $(type -t $_opt "$_cmd" | uniq); do
case $_type in
alias) \builtin alias "$_cmd" 2>/dev/null ;;
function) echo -n 'function '; \builtin declare -f "$_cmd" ;;
file) env which $_opt "$_cmd" | xargs -I{} stat -c $_fmt {} ;;
*) echo $_type $_cmd ;;
esac
done
done } | |
$ | type -at printf | # Facepalm |
| alias function builtin file | ||
$ | which printf | |
| alias printf='echo -n alias:\ ; /usr/bin/printf' | ||
$ | unalias printf | |
| $ | which printf | |
function printf ()
{
echo -n function:\ ;
builtin printf "$@"
} | ||
$ | unset -f printf | |
| $ | which -a printf | |
| builtin printf | ||
| '/usr/bin/printf' | ||
$ | time -f%E sleep 5 | # WTF moment |
| -f%E: command not found | ||
$ | builtin time | |
| bash: builtin: time: not a shell builtin | ||
$ | which time | |
| keyword time | ||
$ | which -a which | |
function which ()
{
local _fmt=%n _opt='' _cmd _type;
case "$1" in
-a)
_fmt=%N _opt=-a;
shift
;;
-*)
\builtin printf 'Illegal option %s\nUsage: which [-a] args\n' "$1";
return 2
;;
esac;
for _cmd in "$@";
do
for _type in $(type -t $_opt "$_cmd" | uniq);
do
case $_type in
alias)
\builtin alias "$_cmd" 2> /dev/null
;;
function)
echo -n 'function ';
\builtin declare -f "$_cmd"
;;
file)
env which $_opt "$_cmd" | xargs -I{} stat -c $_fmt {}
;;
*)
echo $_type $_cmd
;;
esac;
done;
done
} | ||
| '/usr/bin/which' -> '/bin/which'
'/bin/which' |