bash - wie man das Ergebnis aus dem Befehl which auf cd weiterleitet

84

Wie kann ich das Ergebnis von einem whichBefehl an cdweiterleiten?

Das versuche ich zu tun:

which oracle | cd
cd < which oracle

Aber keiner von ihnen funktioniert.

Gibt es eine Möglichkeit, dies zu erreichen (anstatt natürlich zu kopieren / einfügen)?

Bearbeiten: Beim zweiten Gedanken würde dieser Befehl fehlschlagen, da die Zieldatei KEIN Ordner / Verzeichnis ist .

Also denke ich nach und arbeite einen besseren Weg aus, um den nachfolgenden "/ oracle" Teil jetzt loszuwerden (sed oder awk oder sogar Perl) :)

Edit: Okay, das habe ich am Ende:

cd `which oracle | sed 's/\/oracle//g'`
Michael Mao
quelle
2
Das gibt Ihnen Befehl, nicht Verzeichnis
Anycorn
Versuchen Sie, das Verzeichnis abzurufen, in dem das Programm installiert ist? dirname, basename ?
Anycorn
@aaa: Sie haben Recht, ich denke, Dirname ist besser, weil es auf "das echte Verzeichnis" verweist, nicht auf einen symbolischen Link zur ausführbaren Oracle-Datei ... weshalb mein sed-Ansatz fehlschlagen würde :)
Michael Mao

Antworten:

124

Sie verwenden Pipe in Fällen, in denen der Befehl Parameter von der Standardeingabe erwartet. ( Mehr dazu ).

Mit cdBefehl ist das nicht der Fall. Das Verzeichnis ist das Befehlsargument. In diesem Fall können Sie die Befehlsersetzung verwenden. Verwenden Sie Backticks oder $(...)speichern Sie den Befehl in einer Variablen, um ihn auszuwerten.

path=`which oracle`
echo $path # just for debug
cd $path

obwohl es viel einfacher gemacht werden kann:

cd `which oracle` 

oder wenn Ihr Pfad Sonderzeichen enthält

cd "`which oracle`"

oder

cd $(which oracle)

Dies entspricht der Backtick-Notation, wird jedoch empfohlen (Backticks können mit Apostrophen verwechselt werden).

.. aber es sieht so aus wie du willst:

cd $(dirname $(which oracle))

(was Ihnen zeigt, dass Sie das Verschachteln einfach verwenden können)

$(...) (sowie Backticks) funktionieren auch in Zeichenfolgen in doppelten Anführungszeichen, was hilfreich ist, wenn das Ergebnis möglicherweise Leerzeichen enthält.

cd "$(dirname "$(which oracle)")"

(Beachten Sie, dass für beide Ausgänge doppelte Anführungszeichen erforderlich sind.)

Mykhal
quelle
Cool. Könnten Sie bitte etwas erklären, was hier los ist? Das sieht aus wie eine variable Dereferenzierung; Gibt es eine temporäre Standardvariable, in die die Ergebnisse eines Befehls verschoben werden?
Nate W.
Ahhh, ich habe vergessen, über die Backticks zu zwingen :(
Michael Mao
4
Sie benötigen ein weiteres Anführungszeichen : cd "$(dirname "$(which oracle)")".
Philipp
Das |öffnet einen neuen Prozess, so dass selbst wenn cdvon STDIN gelesen, cmd | cddies nicht funktionieren würde (dh das aktuelle Verzeichnis im ursprünglichen Prozess würde gleich bleiben).
Kyle Strand
23

Mit dirname, um das Verzeichnis zu erhalten:

cd $(which oracle | xargs dirname)

BEARBEITEN: Achten Sie auf Pfade, die Leerzeichen enthalten, siehe @ anishpatel Kommentar unten


quelle
2
Verwenden Sie cd "$(which oracle | xargs -0 dirname)"diese Option, wenn der Pfad Leerzeichen enthalten kann. Das Flag -0 teilt die Eingabe eher durch Null als durch Leerzeichen.
Anishpatel
9
cd `which oracle`

Beachten Sie, dass dies Backticks sind (im Allgemeinen die Taste links von 1 auf einer US-Tastatur).

Cfreak
quelle
1
Dies funktioniert nicht, wenn der Pfad Leerzeichen oder andere "Sonderzeichen" enthält und Sie den Dateinamen entfernen müssen.
Philipp
@Philipp Sie können dies verwenden, wenn Ihr Pfad Sonderzeichen hatcd "`which oracle`"
Ram Patra
4

OK, hier eine Lösung, die korrektes Zitieren verwendet:

cd "$(dirname "$(which oracle)")"

Vermeiden Sie Backticks, sie sind weniger lesbar und zitieren immer Prozessersetzungen.

Philipp
quelle
2

Sie brauchen keine Pipe, Sie können mit der Bash-Parametererweiterung machen, was Sie wollen!

Weiterer Tipp: Verwenden Sie "type -P" anstelle des externen Befehls "which", wenn Sie Bash verwenden.

# test
touch /ls
chmod +x /ls
cmd='ls'
PATH=/:$PATH
if cmdpath="$(type -P "$cmd")" && cmdpath="${cmdpath%/*}" ; then
   cd "${cmdpath:-/}" || { echo "Could not cd to: ${cmdpath:-/}"; exit 1; }
else
   echo "No such program in PATH search directories: ${cmd}"
   exit 1
fi
Bashfu
quelle
1

Als Antwort auf Ihre bearbeitete Frage können Sie den Namen des Befehls entfernen, indem Sie dirname:

cd $(dirname `which oracle`)
David Z.
quelle
Dies funktioniert nicht, wenn der Pfad Leerzeichen oder andere "Sonderzeichen" enthält.
Philipp
1
Einfach durch doppelte Anführungszeichen zu beheben.
David Z