bash - come reindirizzare il risultato da quale comando a cd


87

Come potrei reindirizzare il risultato di un whichcomando a cd?

Questo è quello che sto cercando di fare:

which oracle | cd
cd < which oracle

Ma nessuno di loro funziona.

C'è un modo per ottenere questo risultato (piuttosto che copiare / incollare ovviamente)?

Modifica: a pensarci bene, questo comando fallirebbe, perché il file di destinazione NON è una cartella / directory .

Quindi sto pensando e lavorando a un modo migliore per sbarazzarmi della parte finale "/ oracle" ora (sed o awk, o anche Perl) :)

Modifica: ok, è quello che ho alla fine:

cd `which oracle | sed 's/\/oracle//g'`

2
che ti dà il comando, non la directory
Anycorn

stai cercando di ottenere la directory in cui è installato il programma? dirname, basename ?
Anycorn

@aaa: hai ragione, penso che dirname sia migliore perché indica "la dir reale" non un collegamento simbolico all'eseguibile di Oracle ... ecco perché il mio sed apporach fallirebbe :)
Michael Mao

Risposte:


129

Si utilizza pipe nei casi in cui il comando richiede parametri dall'input standard. ( Maggiori informazioni su questo ).

Con il cdcomando non è così. La directory è l'argomento del comando. In tal caso, è possibile utilizzare la sostituzione del comando. Usa i backtick o $(...)per valutare il comando, memorizzalo nella variabile ..

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

anche se può essere fatto in un modo molto più semplice:

cd `which oracle` 

o se il tuo percorso ha caratteri speciali

cd "`which oracle`"

o

cd $(which oracle)

che è equivalente alla notazione backtick, ma è consigliato (i backtick possono essere confusi con gli apostrofi)

.. ma sembra che tu voglia:

cd $(dirname $(which oracle))

(che ti mostra che puoi usare facilmente l'annidamento)

$(...) (così come i backtick) funzionano anche con stringhe tra virgolette, il che aiuta quando il risultato può eventualmente contenere spazi ..

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

(Nota che entrambi gli output richiedono una serie di virgolette doppie.)


Freddo. Potresti spiegare un po 'cosa sta succedendo qui? Sembra una dereferenziazione variabile; c'è qualche variabile temporanea predefinita in cui vanno i risultati di un comando?
Nate W.

Ahhh, mi ero dimenticato delle battute indietro :(
Michael Mao

4
Avete bisogno di un altro paio di citazioni: cd "$(dirname "$(which oracle)")".
Philipp

La |apre un nuovo processo, quindi, anche se cdleggere da STDIN, cmd | cdnon sarebbe il lavoro (cioè la directory corrente nel processo originale rimarrebbe lo stesso).
Kyle Strand

24

Con dirname per ottenere la directory:

cd $(which oracle | xargs dirname)

MODIFICA: fai attenzione ai percorsi che contengono spazi, vedi il commento @anishpatel di seguito


3
Utilizzare cd "$(which oracle | xargs -0 dirname)"se il percorso può contenere spazi vuoti. Il flag -0 divide l'input da null invece che da spazi.
anishpatel

9
cd `which oracle`

Nota che si tratta di backtick (generalmente il tasto a sinistra di 1 su una tastiera americana)


1
Questo non funziona se il percorso contiene spazi o altri caratteri "speciali" e devi rimuovere il nome del file.
Philipp

@Philipp puoi usarlo se il tuo percorso ha caratteri specialicd "`which oracle`"
Ram Patra

4

OK, ecco una soluzione che utilizza la citazione corretta:

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

Evita i backtick, sono meno leggibili e cita sempre le sostituzioni di processo.


2

Non hai bisogno di una pipe, puoi fare quello che vuoi usando l'espansione dei parametri di Bash!

Ulteriore suggerimento: usa "type -P" invece del comando esterno "which" se stai usando 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

1

In risposta alla tua domanda modificata, puoi rimuovere il nome del comando usando dirname:

cd $(dirname `which oracle`)

Questo non funziona se il percorso contiene spazi o altri caratteri "speciali".
Philipp

1
Facilmente risolvibile citandolo due volte.
David Z

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.