as citações no interior são importantes ou você vai perder todos os seus dados
catamphetamine
11
e a variante que estou usando para obter o pai do diretório de trabalho atual: parentdir=$(dirname `pwd`)
TheGrimmScientist
3
Observe que esse método não é seguro para nomes "feios". Um nome como "-rm -rf" interromperá o comportamento desejado. Provavelmente "." vai também. Não sei se essa é a melhor maneira, mas criei uma pergunta "focada na correção" separada aqui: stackoverflow.com/questions/40700119/…
VasiliNovikov
4
@Christopher Shroba Sim, eu omiti as aspas e, em seguida, meu disco rígido acabou parcialmente limpo. Não me lembro exatamente do que aconteceu: presumivelmente, um diretório em branco com aspas em branco fez com que ele apagasse o diretório pai em vez do diretório de destino - meu script apenas apagou a pasta / home / xxx /.
catamphetamine
3
tudo bem, então não há nada no comando que possa causar a perda de dados, a menos que você já esteja emitindo um comando de exclusão, certo? Era apenas uma questão do caminho que você estava tentando remover, dividindo um caractere de espaço e removendo muito mais do que o esperado?
Christopher Shroba 01/12/16
18
... mas o que é "visto aqui " está quebrado. Aqui está a correção:
Basta usar echo $(cd ../ && pwd)enquanto trabalha no diretório cujo diretório pai você deseja descobrir. Essa cadeia também tem o benefício adicional de não ter barras à direita.
O uso evalNÃO é ótimo se houver alguma chance de analisar a entrada do usuário que possa colocá-lo em algum lugar que você não espera ou executar coisas ruins no sistema. Você pode usar em pushd $dir 2>&1 >/dev/null && pwd && popd 2>&1 >/dev/nullvez do eval?
precisa saber é o seguinte
2
Você não precisa de evalnada: apenas faça parentdir=$(cd -- "$dir" && pwd). Como o cdé executado em um subshell, você não precisa cdvoltar para onde estávamos. O --é aqui no caso a expansão do $dircomeça com um hífen. O &&é apenas para evitar parentdirter um conteúdo não vazio quando cdnão foi bem-sucedido.
gniourf_gniourf
8
Motivação para outra resposta
Eu gosto de um código muito curto, claro e garantido. Ponto de bônus se não executar um programa externo, já que no dia em que você precisa processar um grande número de entradas, será visivelmente mais rápido.
Princípio
Não tenho certeza sobre quais garantias você tem e deseja, então ofereça de qualquer maneira.
Se você tiver garantias, poderá fazê-lo com um código muito curto. A idéia é usar o recurso de substituição de texto bash para cortar a última barra e o que se segue.
Responda de casos simples a mais complexos da pergunta original.
Se for garantido que o caminho termina sem nenhuma barra (entrada e saída)
Se o caminho de entrada puder terminar com zero ou uma barra (não mais) e você desejar que o caminho de saída termine sem barra
for P in \
/home/smith/Desktop/Test \
/home/smith/Desktop/Test/do
P_ENDNOSLASH="${P%/}"; echo "${P_ENDNOSLASH%/*}"done/home/smith/Desktop/home/smith/Desktop
Se o caminho de entrada pode ter muitas barras estranhas e você deseja que o caminho de saída termine sem barra
for P in \
/home/smith/Desktop/Test \
/home/smith/Desktop/Test/ \
/home/smith///Desktop////Test//do
P_NODUPSLASH="${P//\/*(\/)/\/}"
P_ENDNOSLASH="${P_NODUPSLASH%%/}"
echo "${P_ENDNOSLASH%/*}";done/home/smith/Desktop/home/smith/Desktop/home/smith/Desktop
Resposta fantástica. Como parece que ele estava procurando uma maneira de fazer isso de dentro de um script (encontre o diretório atual do script e seu pai e faça algo em relação ao local onde o script mora), essa é uma ótima resposta e você pode ter ainda mais controle sobre se a entrada tem uma barra final ou não, usando a expansão de parâmetro contra a ${BASH_SOURCE[0]}qual seria o caminho completo para o script se não fosse originado via sourceou ..
precisa saber é o seguinte
7
Se /home/smith/Desktop/Test/../é o que você deseja:
desculpe, quero dizer, em como um script bash, tenho uma variável com o caminho do arquivo
YTKColumba
A execução desse código me dá o erro bash: dirname 'Test': syntax error: invalid arithmetic operator (error token is "'Test'"). O código vinculado também está errado.
Michael Hoffman
tente apenas correr a dirname Testpartir do diretório Testestá dentro.
Jon Egeland
1
Dependendo se você precisa de caminhos absolutos, convém dar um passo extra:
Obrigado !, exatamente o que eu estava procurando.
27719 Josue Abarca
0
feio, mas eficiente
functionParentdir()
{
local lookFor_ parent_ switch_ i_
lookFor_="$1"#if it is not a file, we need the grand parent[-f "$lookFor_"]|| switch_="/.."#length of search string
i_="${#lookFor_}"#remove string one by one until it make sens for the systemwhile["$i_"-ge 0]&&[!-d "${lookFor_:0:$i_}"];do
let i_--done#get real path
parent_="$(realpath "${lookFor_:0:$i_}$switch_")"#done
echo "
lookFor_: $1
{lookFor_:0:$i_}: ${lookFor_:0:$i_}
realpath {lookFor_:0:$i_}: $(realpath ${lookFor_:0:$i_})
parent_: $parent_
"
Se por qualquer motivo você está interessado em navegar até um determinado número de diretórios que você também pode fazer: nth_path=$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd ../../../ && pwd). Isso daria 3 diretórios para os pais
..
', mas talvez isso não seja exatamente o que você tinha em mente.Respostas:
Funciona se houver uma barra à direita também.
fonte
parentdir=$(dirname `pwd`)
... mas o que é "visto aqui " está quebrado. Aqui está a correção:
fonte
Basta usar
echo $(cd ../ && pwd)
enquanto trabalha no diretório cujo diretório pai você deseja descobrir. Essa cadeia também tem o benefício adicional de não ter barras à direita.fonte
echo
aqui.Claramente, o diretório pai é fornecido simplesmente acrescentando o nome do arquivo ponto a ponto:
Mas você deve querer o caminho resolvido (um caminho absoluto sem nenhum componente de caminho ponto a ponto):
O problema com as principais respostas usadas
dirname
é que elas não funcionam quando você insere um caminho com pontos-ponto:Isso é mais poderoso :
Você pode alimentá-lo
/home/smith/Desktop/Test/..
, mas também caminhos mais complexos, como:EDIT: se não funcionar, verifique
cd
se não foi modificado, como é prática comum às vezes,fonte
eval
NÃO é ótimo se houver alguma chance de analisar a entrada do usuário que possa colocá-lo em algum lugar que você não espera ou executar coisas ruins no sistema. Você pode usar empushd $dir 2>&1 >/dev/null && pwd && popd 2>&1 >/dev/null
vez doeval
?eval
nada: apenas façaparentdir=$(cd -- "$dir" && pwd)
. Como ocd
é executado em um subshell, você não precisacd
voltar para onde estávamos. O--
é aqui no caso a expansão do$dir
começa com um hífen. O&&
é apenas para evitarparentdir
ter um conteúdo não vazio quandocd
não foi bem-sucedido.Motivação para outra resposta
Eu gosto de um código muito curto, claro e garantido. Ponto de bônus se não executar um programa externo, já que no dia em que você precisa processar um grande número de entradas, será visivelmente mais rápido.
Princípio
Não tenho certeza sobre quais garantias você tem e deseja, então ofereça de qualquer maneira.
Se você tiver garantias, poderá fazê-lo com um código muito curto. A idéia é usar o recurso de substituição de texto bash para cortar a última barra e o que se segue.
Responda de casos simples a mais complexos da pergunta original.
Se for garantido que o caminho termina sem nenhuma barra (entrada e saída)
Se for garantido que o caminho termine com exatamente uma barra (entrada e saída)
Se o caminho de entrada puder terminar com zero ou uma barra (não mais) e você desejar que o caminho de saída termine sem barra
Se o caminho de entrada pode ter muitas barras estranhas e você deseja que o caminho de saída termine sem barra
fonte
${BASH_SOURCE[0]}
qual seria o caminho completo para o script se não fosse originado viasource
ou.
.Se
/home/smith/Desktop/Test/../
é o que você deseja:como visto aqui .
fonte
bash: dirname 'Test': syntax error: invalid arithmetic operator (error token is "'Test'")
. O código vinculado também está errado.dirname Test
partir do diretórioTest
está dentro.Dependendo se você precisa de caminhos absolutos, convém dar um passo extra:
fonte
use isto:
export MYVAR="$(dirname "$(dirname "$(dirname "$(dirname $PWD)")")")"
se você quiser o 4º diretório paiexport MYVAR="$(dirname "$(dirname "$(dirname $PWD)")")"
se você quiser o terceiro diretório paiexport MYVAR="$(dirname "$(dirname $PWD)")"
se você quiser o segundo diretório paifonte
feio, mas eficiente
{
}
fonte
Iniciado a partir da idéia / comentário Charles Duffy - 17/12/14 às 5:32 sobre o tópico Obter o nome do diretório atual (sem o caminho completo) em um script Bash
fonte
Se por qualquer motivo você está interessado em navegar até um determinado número de diretórios que você também pode fazer:
nth_path=$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd ../../../ && pwd)
. Isso daria 3 diretórios para os paisfonte