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

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.)


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


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).


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.


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

1

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

cd $(dirname `which oracle`)

Dies funktioniert nicht, wenn der Pfad Leerzeichen oder andere "Sonderzeichen" enthält.
Philipp

1
Einfach durch doppelte Anführungszeichen zu beheben.
David Z

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.