bash - como canalizar o resultado do comando para cd


87

Como posso canalizar o resultado de um whichcomando para cd?

Isso é o que estou tentando fazer:

which oracle | cd
cd < which oracle

Mas nenhum deles funciona.

Existe uma maneira de fazer isso (em vez de copiar / colar, é claro)?

Edit: pensando bem, este comando falhará, porque o arquivo de destino NÃO é uma pasta / diretório .

Então, estou pensando e trabalhando em uma maneira melhor de me livrar da parte "/ oracle" final agora (sed ou awk, ou mesmo Perl) :)

Edit: Ok, isso é o que eu tenho no final:

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

2
que lhe dá comando, não diretório
Anycorn

você está tentando obter o diretório onde o programa está instalado? dirname, basename ?
Anycorn

@aaa: você está certo, acho que dirname é melhor porque aponta para "o diretório real" e não um link simbólico para o executável do oráculo ... razão pela qual meu apporach sed falharia :)
Michael Mao

Respostas:


128

Você usa o pipe nos casos em que o comando espera parâmetros da entrada padrão. ( Mais sobre isso ).

Com o cdcomando, esse não é o caso. O diretório é o argumento do comando. Nesse caso, você pode usar a substituição de comando. Use crases ou $(...)para avaliar o comando, armazene-o na variável.

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

embora possa ser feito de uma maneira muito mais simples:

cd `which oracle` 

ou se o seu caminho tem caracteres especiais

cd "`which oracle`"

ou

cd $(which oracle)

que é equivalente à notação de crase, mas é recomendado (crases podem ser confundidos com apóstrofos)

.. mas parece que você quer:

cd $(dirname $(which oracle))

(o que mostra que você pode usar o aninhamento facilmente)

$(...) (bem como crases) também funcionam em strings entre aspas duplas, o que ajuda quando o resultado pode eventualmente conter espaços.

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

(Observe que ambas as saídas requerem um conjunto de aspas duplas.)


Legal. Você poderia explicar um pouco sobre o que está acontecendo aqui? Isso parece uma desreferência de variável; existe alguma variável temporária padrão para onde vão os resultados de um comando?
Nate W.

Ahhh, esqueci-me dos acúmulos :(
Michael Mao

4
Você precisa de outro par de aspas: cd "$(dirname "$(which oracle)")".
Philipp

O |abre um novo processo, portanto, mesmo se cdlido de STDIN, cmd | cdnão funcionaria (ou seja, o diretório atual no processo original permaneceria o mesmo).
Kyle Strand,

23

Com dirname para obter o diretório:

cd $(which oracle | xargs dirname)

EDITAR: cuidado com os caminhos que contêm espaços, veja o comentário @anishpatel abaixo


2
Use cd "$(which oracle | xargs -0 dirname)"se o caminho puder conter espaços em branco. O sinalizador -0 divide a entrada por nulo em vez de espaço em branco.
anishpatel

9
cd `which oracle`

Observe que esses são crases (geralmente a tecla à esquerda de 1 em um teclado americano)


1
Isso não funciona se o caminho contiver espaços ou outros caracteres "especiais" e você tiver que retirar o nome do arquivo.
Philipp

@Philipp, você pode usar isso se o seu caminho tiver caracteres especiaiscd "`which oracle`"
Ram Patra

4

OK, aqui está uma solução que usa aspas corretas:

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

Evite crases, eles são menos legíveis e sempre mencionam substituições de processos.


2

Você não precisa de um tubo, você pode fazer o que quiser usando a expansão do parâmetro Bash!

Dica adicional: use "type -P" em vez do comando externo "which" se estiver usando o 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

Em resposta à sua pergunta editada, você pode retirar o nome do comando usando dirname:

cd $(dirname `which oracle`)

Isso não funciona se o caminho contiver espaços ou outros caracteres "especiais".
Philipp

1
Facilmente corrigido citando-o duas vezes.
David Z

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.