Dlaczego „whereis” i „które” nie pokazują mi miejsca dowodzenia?

14

Jakie są powody, dla których polecenia lubią whereislub whichnie pokazują lokalizacji polecenia? Np. Mam NVM i chcę wiedzieć, gdzie się znajduje, ale żadne z tych poleceń nie pomaga mi znaleźć pliku binarnego. Czy powinienem używać tylko findw tym przypadku?

AKTUALIZACJA

Oto długi wynik type nvm

$ type nvm
nvm is a function
nvm ()
{
    if [ $# -lt 1 ]; then
        nvm help;
        return;
    fi;
    local uname="$(uname -a)";
    local os=;
    local arch="$(uname -m)";
    case "$uname" in
        Linux\ *)
            os=linux
        ;;
        Darwin\ *)
            os=darwin
        ;;
        SunOS\ *)
            os=sunos
        ;;
        FreeBSD\ *)
            os=freebsd
        ;;
    esac;
    case "$uname" in
        *x86_64*)
            arch=x64
        ;;
        *i*86*)
            arch=x86
        ;;
        *armv6l*)
            arch=arm-pi
        ;;
    esac;
    local VERSION;
    local ADDITIONAL_PARAMETERS;
    case $1 in
        "help")
            echo;
            echo "Node Version Manager";
            echo;
            echo "Usage:";
            echo "    nvm help                    Show this message";
            echo "    nvm install [-s] <version>  Download and install a <version>, [-s] from source";
            echo "    nvm uninstall <version>     Uninstall a version";
            echo "    nvm use <version>           Modify PATH to use <version>";
            echo "    nvm run <version> [<args>]  Run <version> with <args> as arguments";
            echo "    nvm current                 Display currently activated version";
            echo "    nvm ls                      List installed versions";
            echo "    nvm ls <version>            List versions matching a given description";
            echo "    nvm ls-remote               List remote versions available for install";
            echo "    nvm deactivate              Undo effects of NVM on current shell";
            echo "    nvm alias [<pattern>]       Show all aliases beginning with <pattern>";
            echo "    nvm alias <name> <version>  Set an alias named <name> pointing to <version>";
            echo "    nvm unalias <name>          Deletes the alias named <name>";
            echo "    nvm copy-packages <version> Install global NPM packages contained in <version> to current version";
            echo;
            echo "Example:";
            echo "    nvm install v0.10.24        Install a specific version number";
            echo "    nvm use 0.10                Use the latest available 0.10.x release";
            echo "    nvm run 0.10.24 myApp.js    Run myApp.js using node v0.10.24";
            echo "    nvm alias default 0.10.24   Set default node version on a shell";
            echo;
            echo "Note:";
            echo "    to remove, delete or uninstall nvm - just remove ~/.nvm, ~/.npm and ~/.bower folders";
            echo
        ;;
        "install")
            local binavail;
            local t;
            local url;
            local sum;
            local tarball;
            local shasum='shasum';
            local nobinary;
            if ! has "curl"; then
                echo 'NVM Needs curl to proceed.' 1>&2;
            fi;
            if ! has "shasum"; then
                shasum='sha1sum';
            fi;
            if [ $# -lt 2 ]; then
                nvm help;
                return;
            fi;
            shift;
            nobinary=0;
            if [ "$1" = "-s" ]; then
                nobinary=1;
                shift;
            fi;
            if [ "$os" = "freebsd" ]; then
                nobinary=1;
            fi;
            VERSION=`nvm_remote_version $1`;
            ADDITIONAL_PARAMETERS='';
            shift;
            while [ $# -ne 0 ]; do
                ADDITIONAL_PARAMETERS="$ADDITIONAL_PARAMETERS $1";
                shift;
            done;
            [ -d "$NVM_DIR/$VERSION" ] && echo "$VERSION is already installed." && return;
            if [ $nobinary -ne 1 ]; then
                if [ -n "$os" ]; then
                    binavail=;
                    case "$VERSION" in
                        v0.8.[012345])
                            binavail=0
                        ;;
                        v0.[1234567].*)
                            binavail=0
                        ;;
                        *)
                            binavail=1
                        ;;
                    esac;
                    if [ $binavail -eq 1 ]; then
                        t="$VERSION-$os-$arch";
                        url="http://nodejs.org/dist/$VERSION/node-${t}.tar.gz";
                        sum=`curl -s http://nodejs.org/dist/$VERSION/SHASUMS.txt | \grep node-${t}.tar.gz | awk '{print $1}'`;
                        local tmpdir="$NVM_DIR/bin/node-${t}";
                        local tmptarball="$tmpdir/node-${t}.tar.gz";
                        if ( mkdir -p "$tmpdir" && curl -L -C - --progress-bar $url -o "$tmptarball" && nvm_checksum `${shasum} "$tmptarball" | awk '{print $1}'` $sum && tar -xzf "$tmptarball" -C "$tmpdir" --strip-components 1 && rm -f "$tmptarball" && mv "$tmpdir" "$NVM_DIR/$VERSION" ); then
                            nvm use $VERSION;
                            return;
                        else
                            echo "Binary download failed, trying source." 1>&2;
                            rm -rf "$tmptarball" "$tmpdir";
                        fi;
                    fi;
                fi;
            fi;
            echo "Additional options while compiling: $ADDITIONAL_PARAMETERS";
            tarball='';
            sum='';
            make='make';
            if [ "$os" = "freebsd" ]; then
                make='gmake';
            fi;
            local tmpdir="$NVM_DIR/src";
            local tmptarball="$tmpdir/node-$VERSION.tar.gz";
            if [ "`curl -Is "http://nodejs.org/dist/$VERSION/node-$VERSION.tar.gz" | \grep '200 OK'`" != '' ]; then
                tarball="http://nodejs.org/dist/$VERSION/node-$VERSION.tar.gz";
                sum=`curl -s http://nodejs.org/dist/$VERSION/SHASUMS.txt | \grep node-$VERSION.tar.gz | awk '{print $1}'`;
            else
                if [ "`curl -Is "http://nodejs.org/dist/node-$VERSION.tar.gz" | \grep '200 OK'`" != '' ]; then
                    tarball="http://nodejs.org/dist/node-$VERSION.tar.gz";
                fi;
            fi;
            if ( [ ! -z $tarball ] && mkdir -p "$tmpdir" && curl -L --progress-bar $tarball -o "$tmptarball" && if [ "$sum" = "" ]; then
                :;
            else
                nvm_checksum `${shasum} "$tmptarball" | awk '{print $1}'` $sum;
            fi && tar -xzf "$tmptarball" -C "$tmpdir" && cd "$tmpdir/node-$VERSION" && ./configure --prefix="$NVM_DIR/$VERSION" $ADDITIONAL_PARAMETERS && $make && rm -f "$NVM_DIR/$VERSION" 2> /dev/null && $make install ); then
                nvm use $VERSION;
                if ! has "npm"; then
                    echo "Installing npm...";
                    if [[ "`expr match $VERSION '\(^v0\.1\.\)'`" != '' ]]; then
                        echo "npm requires node v0.2.3 or higher";
                    else
                        if [[ "`expr match $VERSION '\(^v0\.2\.\)'`" != '' ]]; then
                            if [[ "`expr match $VERSION '\(^v0\.2\.[0-2]$\)'`" != '' ]]; then
                                echo "npm requires node v0.2.3 or higher";
                            else
                                curl https://npmjs.org/install.sh | clean=yes npm_install=0.2.19 sh;
                            fi;
                        else
                            curl https://npmjs.org/install.sh | clean=yes sh;
                        fi;
                    fi;
                fi;
            else
                echo "nvm: install $VERSION failed!";
                return 1;
            fi
        ;;
        "uninstall")
            [ $# -ne 2 ] && nvm help && return;
            if [[ $2 == `nvm_version` ]]; then
                echo "nvm: Cannot uninstall currently-active node version, $2.";
                return 1;
            fi;
            VERSION=`nvm_version $2`;
            if [ ! -d $NVM_DIR/$VERSION ]; then
                echo "$VERSION version is not installed...";
                return;
            fi;
            t="$VERSION-$os-$arch";
            rm -rf "$NVM_DIR/src/node-$VERSION" "$NVM_DIR/src/node-$VERSION.tar.gz" "$NVM_DIR/bin/node-${t}" "$NVM_DIR/bin/node-${t}.tar.gz" "$NVM_DIR/$VERSION" 2> /dev/null;
            echo "Uninstalled node $VERSION";
            for A in `\grep -l $VERSION $NVM_DIR/alias/* 2>/dev/null`;
            do
                nvm unalias `basename $A`;
            done
        ;;
        "deactivate")
            if [[ $PATH == *$NVM_DIR/*/bin* ]]; then
                export PATH=${PATH%$NVM_DIR/*/bin*}${PATH#*$NVM_DIR/*/bin:};
                hash -r;
                echo "$NVM_DIR/*/bin removed from \$PATH";
            else
                echo "Could not find $NVM_DIR/*/bin in \$PATH";
            fi;
            if [[ $MANPATH == *$NVM_DIR/*/share/man* ]]; then
                export MANPATH=${MANPATH%$NVM_DIR/*/share/man*}${MANPATH#*$NVM_DIR/*/share/man:};
                echo "$NVM_DIR/*/share/man removed from \$MANPATH";
            else
                echo "Could not find $NVM_DIR/*/share/man in \$MANPATH";
            fi;
            if [[ $NODE_PATH == *$NVM_DIR/*/lib/node_modules* ]]; then
                export NODE_PATH=${NODE_PATH%$NVM_DIR/*/lib/node_modules*}${NODE_PATH#*$NVM_DIR/*/lib/node_modules:};
                echo "$NVM_DIR/*/lib/node_modules removed from \$NODE_PATH";
            else
                echo "Could not find $NVM_DIR/*/lib/node_modules in \$NODE_PATH";
            fi
        ;;
        "use")
            if [ $# -eq 0 ]; then
                nvm help;
                return;
            fi;
            if [ $# -eq 1 ]; then
                rc_nvm_version;
                if [ ! -z $RC_VERSION ]; then
                    VERSION=`nvm_version $RC_VERSION`;
                fi;
            else
                VERSION=`nvm_version $2`;
            fi;
            if [ -z $VERSION ]; then
                nvm help;
                return;
            fi;
            if [ -z $VERSION ]; then
                VERSION=`nvm_version $2`;
            fi;
            if [ ! -d "$NVM_DIR/$VERSION" ]; then
                echo "$VERSION version is not installed yet";
                return 1;
            fi;
            if [[ $PATH == *$NVM_DIR/*/bin* ]]; then
                PATH=${PATH%$NVM_DIR/*/bin*}$NVM_DIR/$VERSION/bin${PATH#*$NVM_DIR/*/bin};
            else
                PATH="$NVM_DIR/$VERSION/bin:$PATH";
            fi;
            if [ -z "$MANPATH" ]; then
                MANPATH=$(manpath);
            fi;
            MANPATH=${MANPATH#*$NVM_DIR/*/man:};
            if [[ $MANPATH == *$NVM_DIR/*/share/man* ]]; then
                MANPATH=${MANPATH%$NVM_DIR/*/share/man*}$NVM_DIR/$VERSION/share/man${MANPATH#*$NVM_DIR/*/share/man};
            else
                MANPATH="$NVM_DIR/$VERSION/share/man:$MANPATH";
            fi;
            if [[ $NODE_PATH == *$NVM_DIR/*/lib/node_modules* ]]; then
                NODE_PATH=${NODE_PATH%$NVM_DIR/*/lib/node_modules*}$NVM_DIR/$VERSION/lib/node_modules${NODE_PATH#*$NVM_DIR/*/lib/node_modules};
            else
                NODE_PATH="$NVM_DIR/$VERSION/lib/node_modules:$NODE_PATH";
            fi;
            export PATH;
            hash -r;
            export MANPATH;
            export NODE_PATH;
            export NVM_PATH="$NVM_DIR/$VERSION/lib/node";
            export NVM_BIN="$NVM_DIR/$VERSION/bin";
            echo "Now using node $VERSION"
        ;;
        "run")
            if [ $# -lt 2 ]; then
                nvm help;
                return;
            fi;
            VERSION=`nvm_version $2`;
            if [ ! -d $NVM_DIR/$VERSION ]; then
                echo "$VERSION version is not installed yet";
                return;
            fi;
            if [[ $NODE_PATH == *$NVM_DIR/*/lib/node_modules* ]]; then
                RUN_NODE_PATH=${NODE_PATH%$NVM_DIR/*/lib/node_modules*}$NVM_DIR/$VERSION/lib/node_modules${NODE_PATH#*$NVM_DIR/*/lib/node_modules};
            else
                RUN_NODE_PATH="$NVM_DIR/$VERSION/lib/node_modules:$NODE_PATH";
            fi;
            echo "Running node $VERSION";
            NODE_PATH=$RUN_NODE_PATH $NVM_DIR/$VERSION/bin/node "${@:3}"
        ;;
        "ls" | "list")
            print_versions "`nvm_ls $2`";
            if [ $# -eq 1 ]; then
                echo -ne "current: \t";
                nvm_version current;
                nvm alias;
            fi;
            return
        ;;
        "ls-remote" | "list-remote")
            print_versions "`nvm_ls_remote $2`";
            return
        ;;
        "current")
            echo -ne "current: \t";
            nvm_version current
        ;;
        "alias")
            mkdir -p $NVM_DIR/alias;
            if [ $# -le 2 ]; then
                for ALIAS in $(nvm_set_nullglob; echo $NVM_DIR/alias/$2* );
                do
                    DEST=`cat $ALIAS`;
                    VERSION=`nvm_version $DEST`;
                    if [ "$DEST" = "$VERSION" ]; then
                        echo "$(basename $ALIAS) -> $DEST";
                    else
                        echo "$(basename $ALIAS) -> $DEST (-> $VERSION)";
                    fi;
                done;
                return;
            fi;
            if [ ! "$3" ]; then
                rm -f $NVM_DIR/alias/$2;
                echo "$2 -> *poof*";
                return;
            fi;
            mkdir -p $NVM_DIR/alias;
            VERSION=`nvm_version $3`;
            if [ $? -ne 0 ]; then
                echo "! WARNING: Version '$3' does not exist." 1>&2;
            fi;
            echo $3 > "$NVM_DIR/alias/$2";
            if [ ! "$3" = "$VERSION" ]; then
                echo "$2 -> $3 (-> $VERSION)";
            else
                echo "$2 -> $3";
            fi
        ;;
        "unalias")
            mkdir -p $NVM_DIR/alias;
            [ $# -ne 2 ] && nvm help && return;
            [ ! -f $NVM_DIR/alias/$2 ] && echo "Alias $2 doesn't exist!" && return;
            rm -f $NVM_DIR/alias/$2;
            echo "Deleted alias $2"
        ;;
        "copy-packages")
            if [ $# -ne 2 ]; then
                nvm help;
                return;
            fi;
            local VERSION=`nvm_version $2`;
            local ROOT=`(nvm use $VERSION && npm -g root) | tail -n1`;
            local ROOTDEPTH=$((`echo $ROOT | sed 's/[^\/]//g'|wc -m` -1));
            local INSTALLS;
            INSTALLS=(`nvm use $VERSION > /dev/null && npm -g -p ll | \grep "$ROOT\/[^/]\+$" | cut -d '/' -f $(($ROOTDEPTH + 2)) | cut -d ":" -f 2 | \grep -v npm | tr "\n" " "`);
            npm install -g ${INSTALLS[@]}
        ;;
        "clear-cache")
            rm -f $NVM_DIR/v* 2> /dev/null;
            echo "Cache cleared."
        ;;
        "version")
            print_versions "`nvm_version $2`"
        ;;
        *)
            nvm help
        ;;
    esac
}
Witalij Korsakow
źródło
@BroSlow to typ źródła nvm. Nie potrzebuję tego Chcę wiedzieć, gdzie się znajduje
Witalij Korsakow
Co? typ robi prawie to samo, co robi, z wyjątkiem uzyskiwania dostępu do większej liczby lokalizacji (aliasy, funkcje itp.), jest szybszy, bardziej przenośny itp.
@BroSlow zobacz aktualizację proszę
Vitalii Korsakov
Jeśli polecenie jest aliasem, możesz użyć „wpisz” <twoje polecenie>, aby sprawdzić alias.
Sagar Jagnade

Odpowiedzi:

5

whichNarzędzie przeszukuje tylko istniejącą ścieżkę do plików, więc jeśli nie można wpisać „NVM” i mieć go uruchomić NVM, wtedy nie będzie go zlokalizować.

Z drugiej strony whereisprzeszukuje zakodowaną listę ścieżek do programu, jego strony podręcznika i katalogu źródłowego. Możliwe, że whereis coś znajdzie, jeśli nvm nie znajduje się na twojej ścieżce, ale jeśli nvm nie znajduje się na zakodowanej liście ścieżek, w których przeszukuje, podobnie się nie powiedzie.

Jak sugerujesz, findjest znacznie bardziej elastycznym narzędziem do wyszukiwania dowolnej ścieżki dla dowolnego typu pliku, który możesz określić. Jeśli gdziekolwiek w twoim systemie znajduje się plik wykonywalny nvm, find może zostać użyty do wyłapania go, niezależnie od tego, czy znajduje się on na ścieżce systemowej.

Czwarta opcja do zbadania to locatepolecenie, które wykorzystuje indeksowaną bazę danych plików w systemie, aby szybko znaleźć plik w dowolnym miejscu w systemie, z podobnie prostym wywołaniem, do którego lub gdzie, np.locate nvm

Jeremy Sturdivant
źródło
whichzachowuje się w ten sposób poprawnie, jeśli używasz wariantu powłoki C, takiego jak cshlub tcsh. Może działać poprawnie również w innych powłokach. Jednak w bashtym nie działa. zamiast tego bashużywa typepolecenia. Jest całkowicie możliwe, whichaby nie dać ci nic, bashnawet jeśli można pisać nvmi sprawić, by działało.
CXJ,
3

Jeśli użyłeś curl do zainstalowania nvm (i ewentualnie innych metod), zainstaluje się on jako zestaw funkcji powłoki w twoim katalogu domowym, w ukrytym folderze o nazwie .nvm/nvm.sh. Jako że nie jest to polecenie (wyjaśnione w innych odpowiedzi) to dlaczego whereisi whichnie go znaleźć. Zauważ, że ten sam katalog ma Readme.markdown, który zawiera sporo szczegółowych informacji o nvm.

To jest skrypt, który możesz zwinąć, aby zainstalować NVM: https://raw.githubusercontent.com/creationix/nvm/v0.17.3/install.sh

Miałem ten sam problem i przeszukiwałem to, co się instalowało, więc może to być przydatna metoda, aby dowiedzieć się, gdzie mieszkają inne polecenia, gdy tak naprawdę nie są poleceniami.

Oto świetne wyjaśnienie autora nvm o tym, jak działa nvm.sh:

https://github.com/creationix/nvm/issues/521

Krótko mówiąc, nvm jest zbiorem funkcji powłoki i chociaż ma rozszerzenie .sh, w rzeczywistości nie jest skryptem powłoki. Dlatego nie ma uprawnień do wykonywania (i nie należy go zmieniać). Aby go uruchomić, należy go „pozyskać”:

. ~/.nvm/nvm.sh

Kropka jest synonimem polecenia „source”. Sourcing sprawia, że ​​funkcje w pliku są dostępne dla bieżącej powłoki. Jeśli na przykład musisz uruchomić nvm ze skryptu powłoki, który otworzy nową powłokę na czas trwania skryptu, będziesz musiał pobrać nvm w pliku, ponieważ inaczej nie byłby dostępny.

Katharine Osborne
źródło
3

Nie ma bezpośredniego związku z pytaniem, ale czasami whichnie można znaleźć pliku, mimo że plik znajduje się na Twojej ścieżce, i możesz pomyślnie wykonać polecenie w powłoce. Może się to zdarzyć, jeśli używałeś rozszerzeń powłoki na swojej ścieżce: twoja powłoka będzie ich używać, ale whichmoże nie.

Na przykład whichnie uda się znaleźć plików wykonywalnych w tym katalogu (gdzie ~ jest rozszerzany przez powłokę do katalogu domowego): export PATH="$PATH:~/foo/bin"

Jeśli używasz bash, równie dobrze możesz przyzwyczaić się do używania typezamiast which, ponieważ wydaje się, że nie ma tego problemu. Zobacz tę odpowiedź, aby uzyskać więcej alternatyw.

Patogen
źródło
Jest to ważne dla każdego, kto pochodzi z cshlub z tcshprzeszłości. Ukąsza mnie ta bashosobliwość prawie za każdym razem, gdy używam which.
CXJ,
1

Jeśli twoje nvmpolecenie jest w rzeczywistości aliasem lub funkcją powłoki, whichzidentyfikuje je tylko, jeśli użyjesz odpowiedniej opcji (np. --read-aliasLub --read-functions; zobacz which(1)) i whereisbędzie całkowicie bezużyteczne.

Scott
źródło
0

whereisi whichwyszukuj tylko określone lokalizacje.

man whereis:

Narzędzie whereis sprawdza standardowe katalogi binarne dla określonych programów, drukując ścieżki wszystkich znalezionych programów.

man which:

Które narzędzie pobiera listę nazw poleceń i przeszukuje ścieżkę dla każdego pliku wykonywalnego, który zostałby uruchomiony, gdyby te polecenia zostały faktycznie wywołane.

Ścieżka odnosi się do PATHzmiennej środowiskowej. ( Przeczytaj więcej na ten temat )

Więc te narzędzia znajdzie tylko te programy, które znajdują się w jednej z lokalizacji domyślnych (np /bin, /usr/local/binetc.) i może być uruchomiona poprzez wpisanie nazwy polecenia.

Jeśli zainstalowałeś npmgdzieś indziej, np. /home/username/bin/npmA tego katalogu nie ma w twoim PATH, nie zostanie on znaleziony w ten sposób. Musisz użyć np find.

Daniel Beck
źródło
1
Wierzę, że nvmw ŚCIEŻCE, ponieważ mogę uzyskać dostęp do tego polecenia z dowolnego katalogu
Vitalii Korsakov
whichw niektórych przypadkach może nie znaleźć rzeczy na ścieżce bash. Zobacz odpowiedź @ Pathogen powyżej.
CXJ,