Users browsing this thread: 1 Guest(s)
venam
Administrators
Hello fellow nixers,
This thread is about this:
Code:
~ > which which
which: shell built-in command
~ > type -a which  
which is a shell builtin
which is /usr/bin/which
~ > type -a type
type is a shell builtin
~ > type -a whereis
whereis is /usr/bin/whereis
~ > which cat
/usr/bin/cat
~ > type -a cat
cat is /usr/bin/cat
~ > whereis cat
cat: /usr/bin/cat /usr/share/man/man1/cat.1.gz /usr/share/man/man1/cat.1p.gz

Let's list all possible ways to find out where a program is, be it built in or not, POSIX or not.
evbo
Members
I don't know if this is weird or not, but I usually forget about which and do the following:

Code:
$ find / -name "which"
/bin/which

And for fun, here's an example of how to not optimize a search:

Code:
#!/usr/bin/env python3

import os
import re
import sys

def find_file(root, path):
    regex = re.compile(r"^" + re.escape(path) + r"$")
    for root, dirs, files in os.walk(root):
        for file in files:
            if regex.search(file):
                print(os.path.join(root,file))

find_file('/', str(sys.argv[1]))
xero
Long time nixers
* note i'm truncating the output of these commands as an example *

the posix way is to use "command":
Code:
[~]── - command -v 2bwm
/usr/local/bin/2bwm

there's also "whereis":

Code:
[~]── - whereis 2bwm
2bwm: /usr/local/bin/2bwm

the "locate" command finds files by name:

Code:
[~]── - locate 2bwm
/home/xero/dotfiles/2bwm
/home/xero/src/2bwm/2bwm.c
/usr/local/man/man1/2bwm.1
/usr/local/share/man/man1/2bwm.1

but "which" is my favorite:
Code:
[~]── - which 2bwm
/usr/local/bin/2bwm

you can use the "find" utility with the name flag:
Code:
[~]── - find -name 2bwm
./dotfiles/2bwm
./src/2bwm
./src/2bwm/2bwm

you also have other tools you can install to aid in your searching.

"ag", the silver searcher, can search file contents (default) or file and location names with the -g flag
Code:
[~]── - ag -g 2bwm
dotfiles/2bwm/bin/wm
src/2bwm/2bwm.c
src/2bwm/tags
src/2bwm/Makefile

you can get the same results with ack, but it's much slower.
Code:
[~]── - ack -g 2bwm
dotfiles/2bwm/bin/wm
src/2bwm/2bwm.c
src/2bwm/tags
src/2bwm/Makefile

you can also search the inverse way looking for binaries by man page topics using "apropos":

Code:
[~]── - apropos "window manager"
2bwm (1)             - A small and fast keyboard driven window manager with two borders.

package managers can also give you some good info:

on arch "pacman" can display a file install location list based on package name:
Code:
[~]── - pacman -Ql php
php /etc/
php /etc/php/
php /etc/php/conf.d/
php /etc/php/php.ini
php /usr/
php /usr/bin/
php /usr/bin/phar
php /usr/bin/phar.phar
php /usr/bin/php
php /usr/share/man/man1/phar.1.gz
php /usr/share/man/man1/phar.phar.1.gz
php /usr/share/man/man1/php-config.1.gz
php /usr/share/man/man1/php.1.gz

if you use an "rpm" based distribution (centOS, rhel, SUSE, opensuse, etc):

Code:
[~]── - rpm -ql findutils
/bin/find
/usr/bin/find
/usr/bin/xargs

if you use a "dpkg" based dist (debian, ubuntu and it's derivatives):
Code:
[~]── - dpkg --status some_package
[~]── - dpkg --listfiles some_package
[~]── - dpkg --search some_file
alxndr
Registered
Code:
tree -f | grep '/firefox$'
yossarian
Members
I usually use bash's (POSIX) "command" built-in, since it catches aliases and functions in addition to normal utilities on the PATH:

Code:
$ command -v ls
/bin/ls

$ command -v gs
alias gs='git show'

I usually add a function like this to my scripts:

Code:
installed() {
    cmd=$(command -v "${1}")

    [[ -n "${cmd}" ]] && [[ -f "${cmd}" ]]
    return ${?}
}

installed "gcc" || { echo "I need gcc."; exit 1; }

I used to use "which" for the same purpose, but the fact that OS X's version is slightly different was a source of great annoyance when scripting.
venam
Administrators
There seem to be a confusion with some users (neeasade and jkl). When I mentioned "not posix" I didn't mean "not Unix-like".
jkl
Long time nixers
Sorry, that was new to me.

--
<mort> choosing a terrible license just to be spiteful towards others is possibly the most tux0r thing I've ever seen
venam
Administrators
(06-06-2017, 01:17 PM)jkl Wrote: Sorry, that was new to me.
Neeasade had posted a whole "block" about some other OS too, don't be sorry about that.
venam
Administrators
A recent blog post reminded me of this: https://www.madebygps.com/an-intro-to-fi...-in-linux/
neeasade
Grey Hair Nixers
tangently-related: Sometimes in my dotfiles I will wrap a program with some opinionated behavior (EG dmenu, or mpv). When that happens, I need a way to call the original program/fix the name collision. Enter the script `og`:

Code:
#!/bin/sh
# call the original version of some thing in $PATH
og=$1
shift
"$(type -a "$og" | tail -n 1 | sed -E "s/${og}//;s/ is //;")" "$@"

Then, in my 'wrapped' ~/bin/mpv, I can do something like:

Code:
og mpv \
   --write-filename-in-watch-later-config \
   --save-position-on-quit \
   "$@"
z3bra
Grey Hair Nixers
I don't know which shell you're using, but you can do the same by prefixing the command with \ in most shells (even dash(1)):

Code:
% alias ls='ls -l'
% ls
code
data
tmp
% \ls
code data tmp
neeasade
Grey Hair Nixers
The shell is bash, in a scripting context -- and the \ trick is a fair callout for escaping aliases in an interactive context for sure!