Warum zeigen 'wo' und 'welche' mir nicht den Befehlsort?

13

Was sind die Gründe, warum Befehle den Ort des Befehls mögen whereisoder whichnicht anzeigen? ZB habe ich nvm und möchte wissen, wo es sich befindet, aber keiner dieser Befehle hilft mir, die Binärdatei zu finden. Soll ich nur findin diesem Fall verwenden?

AKTUALISIEREN

Hier ist lange Ausgabe von 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
}
Vitalii Korsakov
quelle
@BroSlow gibt die Quelle von ein nvm. Ich brauche es nicht Ich möchte wissen, wo es sich befindet
Vitalii Korsakov
Was? Typ macht so ziemlich das Gleiche, was , außer auf mehr Speicherorte (Aliase, Funktionen usw.)
@ BroSlow siehe Update bitte
Vitalii Korsakov
Wenn der Befehl ein Alias ​​ist, können Sie mit 'type' <Ihr Befehl> den Alias ​​überprüfen.
Sagar Jagnade

Antworten:

5

Das whichDienstprogramm durchsucht Ihren vorhandenen Pfad nur nach Dateien. Wenn Sie also nicht "nvm" eingeben und nvm ausführen lassen können, wird es nicht gefunden.

whereisDurchsucht andererseits eine fest codierte Liste von Pfaden nach dem Programm, seiner Handbuchseite und seinem Quellverzeichnis. Es ist möglich, dass whereis etwas findet, wenn sich nvm nicht in Ihrem Pfad befindet. Wenn sich nvm jedoch nicht in der fest codierten Liste der Pfade befindet, in denen gesucht wird, ist dies ebenfalls nicht erfolgreich.

Wie Sie implizieren, findist es ein viel flexibleres Dienstprogramm zum Durchsuchen eines beliebigen Pfads nach einem beliebigen Dateityp, den Sie angeben können. Wenn sich irgendwo auf Ihrem System eine ausführbare NVM-Datei befindet, kann find verwendet werden, um sie zu suchen, unabhängig davon, ob sie sich in Ihrem Systempfad befindet.

Eine vierte Option, die untersucht werden muss, ist der locateBefehl, der eine indizierte Datenbank mit Dateien auf Ihrem System verwendet, um schnell eine Datei an einer beliebigen Stelle auf Ihrem System zu finden, mit einem ähnlich einfachen Aufruf, zu dem oder wo, zlocate nvm

Jeremy Sturdivant
quelle
whichverhält sich korrekt, wenn Sie eine C-Shell-Variante wie cshoder verwenden tcsh. Es kann auch in anderen Schalen richtig funktionieren. Doch in bashes funktioniert nicht. bashverwendet typestattdessen den Befehl. Es ist durchaus möglich , whichSie geben nichts , bashselbst wenn man kann eingeben nvmund haben es Arbeit.
CXJ
3

Wenn Sie nvm (und möglicherweise andere Methoden) mit curl installiert haben, installiert es sich selbst als eine Reihe von Shell-Funktionen in Ihrem Home-Verzeichnis in einem versteckten Ordner namens .nvm/nvm.sh. Da es sich nicht um einen Befehl handelt (der in den anderen Antworten erläutert wird), ist dies der Grund whereisund kann whichnicht gefunden werden. Beachten Sie, dass dasselbe Verzeichnis eine Readme.markdown-Datei enthält, die einige detaillierte Informationen zu nvm enthält.

Dies ist das Skript, das Sie zur Installation von nvm locken können: https://raw.githubusercontent.com/creationix/nvm/v0.17.3/install.sh

Ich hatte das gleiche Problem und stöberte darin, wo sich die Installation selbst befand. Dies könnte eine nützliche Methode sein, um herauszufinden, wo andere Befehle leben, wenn sie eigentlich keine Befehle sind.

Dies ist eine großartige Erklärung des Autors von nvm, wie nvm.sh funktioniert:

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

Kurz gesagt, nvm ist eine Sammlung von Shell-Funktionen, und obwohl es die Erweiterung .sh hat, ist es eigentlich kein Shell-Skript. Aus diesem Grund verfügt es nicht über ausführbare Berechtigungen (und sollte nicht geändert werden). Um es auszuführen, muss es stattdessen "bezogen" werden:

. ~/.nvm/nvm.sh

Der Punkt ist ein Synonym für den Befehl 'source'. Durch die Beschaffung werden die Funktionen in der Datei für die aktuelle Shell verfügbar. Wenn Sie beispielsweise nvm über ein Shell-Skript ausführen müssen, das für die Dauer des Skripts eine neue Shell öffnet, müssen Sie nvm in der Datei als Quelle angeben, da es sonst nicht verfügbar ist.

Katharine Osborne
quelle
3

Nicht direkt mit der Frage verbunden, kann aber manchmal whichkeine Datei finden, obwohl sich die Datei auf Ihrem Pfad befindet, und Sie können den Befehl in Ihrer Shell erfolgreich ausführen. Dies kann passieren, wenn Sie auf Ihrem Pfad Shell-Erweiterungen verwendet haben: Ihre Shell verwendet diese, whichmöglicherweise jedoch nicht.

Beispielsweise whichwerden in diesem Verzeichnis keine ausführbaren Dateien gefunden (wobei ~ von Ihrer Shell zu Ihrem Home-Verzeichnis erweitert wird): export PATH="$PATH:~/foo/bin"

Wenn Sie bash verwenden, können Sie es sich genauso gut zur Gewohnheit machen, typeanstatt zu verwenden which, da es dieses Problem nicht zu haben scheint. Weitere Alternativen finden Sie in dieser Antwort .

Erreger
quelle
Dies ist wichtig für alle, die aus einem cshoder einem tcshHintergrund stammen. Ich werde bashfast jedes Mal von dieser Besonderheit gebissen, wenn ich sie benutze which.
CXJ
1

Wenn Ihr nvmBefehl tatsächlich ein Alias ​​oder eine Shell-Funktion ist, whichwird er nur identifiziert, wenn Sie eine geeignete Option verwenden (z. B. --read-aliasoder --read-functions; siehe which(1)), und whereisist völlig nutzlos.

Scott
quelle
0

whereisund whichnur bestimmte Orte suchen.

man whereis::

Das Dienstprogramm whereis überprüft die Standard-Binärverzeichnisse auf die angegebenen Programme und druckt die gefundenen Pfade aus.

man which::

Das Dienstprogramm which verwendet eine Liste von Befehlsnamen und durchsucht den Pfad nach jeder ausführbaren Datei, die ausgeführt werden würde, wenn diese Befehle tatsächlich aufgerufen würden.

Pfad bezieht sich auf die PATHUmgebungsvariable. ( Lesen Sie mehr darüber )

Also diese Programme werden nur Programme , die in einem der Standardpositionen (zB sind /bin, /usr/local/binetc.) und kann nur durch Eingabe des Befehls Namen gestartet werden.

Wenn Sie npmz. B. woanders installiert /home/username/bin/npmhaben und sich dieses Verzeichnis nicht in Ihrem befindet PATH, wird es auf diese Weise nicht gefunden. Sie müssen zB verwenden find.

Daniel Beck
quelle
1
Ich glaube, dass nvmin der PATH, da ich von jedem Verzeichnis aus auf diesen Befehl zugreifen kann
Vitalii Korsakov
whichkann in einigen Fällen bei der Verwendung nicht im Pfad gefunden werden bash. Siehe die Antwort von @ Pathogen oben.
CXJ