bash - comment diriger le résultat de la commande which vers cd

87

Comment puis-je diriger le résultat d'une whichcommande vers cd?

C'est ce que j'essaye de faire:

which oracle | cd
cd < which oracle

Mais aucun d'entre eux ne fonctionne.

Existe-t-il un moyen d'y parvenir (plutôt que de copier / coller bien sûr)?

Edit: après réflexion, cette commande échouerait, car le fichier de destination n'est PAS un dossier / répertoire .

Je suis donc en train de réfléchir et de trouver un meilleur moyen de me débarrasser de la partie "/ oracle" de fin maintenant (sed ou awk, ou même Perl) :)

Edit: Ok, c'est ce que j'ai à la fin:

cd `which oracle | sed 's/\/oracle//g'`
Michael Mao
la source
2
qui vous donne la commande, pas le répertoire
Anycorn
essayez-vous d'obtenir le répertoire où le programme est installé? dirname, basename ?
Anycorn
@aaa: vous avez raison, je pense que dirname est meilleur car il pointe vers "le vrai dir" pas un lien symbolique vers l'exécutable oracle ... c'est pourquoi mon apporach sed échouerait :)
Michael Mao

Réponses:

128

Vous utilisez un tube dans les cas où la commande attend des paramètres de l'entrée standard. ( Plus à ce sujet ).

Avec cdcommande ce n'est pas le cas. Le répertoire est l'argument de la commande. Dans ce cas, vous pouvez utiliser la substitution de commande. Utilisez des backticks ou $(...)pour évaluer la commande, stockez-la dans une variable.

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

bien que cela puisse être fait d'une manière beaucoup plus simple:

cd `which oracle` 

ou si votre chemin contient des caractères spéciaux

cd "`which oracle`"

ou

cd $(which oracle)

ce qui équivaut à la notation backtick, mais est recommandé (les backticks peuvent être confondus avec des apostrophes)

.. mais il semble que vous vouliez:

cd $(dirname $(which oracle))

(ce qui vous montre que vous pouvez utiliser l'imbrication facilement)

$(...) (ainsi que les backticks) fonctionnent également dans les chaînes entre guillemets, ce qui est utile lorsque le résultat peut éventuellement contenir des espaces.

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

(Notez que les deux sorties nécessitent un ensemble de guillemets doubles.)

mykhal
la source
Cool. Pourriez-vous s'il vous plaît expliquer un peu ce qui se passe ici? Cela ressemble à un déréférencement variable; y a-t-il une variable temporaire par défaut où vont les résultats d'une commande?
Nate W.
Ahhh, j'ai oublié de préciser les backticks :(
Michael Mao
4
Vous avez besoin d'une autre paire de guillemets: cd "$(dirname "$(which oracle)")".
Philipp
L' |ouvre un nouveau processus, donc même s'il est cdlu à partir de STDIN, cmd | cdne fonctionnerait pas (c'est-à-dire que le répertoire actuel dans le processus d'origine resterait le même).
Kyle Strand
23

Avec dirname pour obtenir le répertoire:

cd $(which oracle | xargs dirname)

EDIT: attention aux chemins contenant des espaces, voir le commentaire @anishpatel ci-dessous


la source
2
À utiliser cd "$(which oracle | xargs -0 dirname)"si le chemin peut contenir des espaces. L'indicateur -0 divise l'entrée par null plutôt que par des espaces.
anishpatel
9
cd `which oracle`

Notez que ce sont des backticks (généralement la touche à gauche de 1 sur un clavier américain)

Cfreak
la source
1
Cela ne fonctionne pas si le chemin contient des espaces ou d'autres caractères "spéciaux" et que vous devez supprimer le nom du fichier.
Philipp
@Philipp, vous pouvez utiliser ceci si votre chemin contient des caractères spéciauxcd "`which oracle`"
Ram Patra
4

OK, voici une solution qui utilise des citations correctes:

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

Évitez les backticks, ils sont moins lisibles et citez toujours les substitutions de processus.

Philipp
la source
2

Vous n'avez pas besoin d'un tube, vous pouvez faire ce que vous voulez en utilisant l'expansion des paramètres Bash!

Astuce supplémentaire: utilisez "type -P" au lieu de la commande externe "which" si vous utilisez Bash.

# 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
la source
1

En réponse à votre question modifiée, vous pouvez supprimer le nom de la commande en utilisant dirname:

cd $(dirname `which oracle`)
David Z
la source
Cela ne fonctionne pas si le chemin contient des espaces ou d'autres caractères "spéciaux".
Philipp
1
Facilement corrigé en le double-citant.
David Z