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' |