Ao escrever um script bash, como obtenho o caminho absoluto do local do arquivo atual?

15

Suponha que eu tenha um arquivo bash chamado myBash.bash. Reside em:

/myDirect/myFolder/myBash.bash

Agora eu quero usar a string /myDirect/myFolder(a localização de myBash.bash) dentro do script. Existe um comando que eu possa usar para encontrar este local?

Edit: A idéia é que eu quero configurar uma pasta zip com código que possa ser iniciado por um script bash dentro desse arquivo zip. Conheço os caminhos de arquivo relativos do código dentro desse arquivo zip, mas não os caminhos absolutos, e preciso deles. Uma maneira seria codificar no caminho ou exigir que o caminho do arquivo seja fornecido como uma variável. No entanto, eu acharia mais fácil se fosse possível para o arquivo bash descobrir onde está sozinho e, em seguida, criar os caminhos relevantes para o outro arquivo a partir do seu conhecimento da estrutura do arquivo zip.

dimpol
fonte
3
Isso pode ser mais adequado para o fluxo de pilha. Verifique estas perguntas: stackoverflow.com/questions/4774054/… stackoverflow.com/questions/59895/… .
Sethos II 17/03/17
1
usar como.? por favor, esclareça
Sergiy Kolodyazhnyy
1
@SethosII esta questão é totalmente sobre o tema aqui
Zanna
1
Eu adicionei mais contexto à pergunta. Eu pensei que poderia haver um comando fácil / óbvio para obter o caminho do arquivo que está sendo executado, mas parece que a resposta é pelo menos não-óbvia.
Dimpol 17/03/19
3
@ Zanna, eu não digo que é offtopic, acho que é apenas mais apropriado e, como mostrado nos links já solicitados e respondidos, várias vezes.
Sethos II 17/03/17

Respostas:

23

Você pode obter o caminho completo como:

realpath "$0"

E, como apontado por Serg, você pode usar dirnamepara remover o nome do arquivo assim

dirname "$(realpath $0)"

ou melhor ainda, para evitar citações difíceis e divisão de palavras com nomes de arquivos difíceis:

temp=$( realpath "$0"  ) && dirname "$temp"

Muito melhor do que minha ideia anterior, que era analisá-la (eu sabia que haveria uma maneira melhor!)

realpath "$0" | sed 's|\(.*\)/.*|\1|'

Notas

  • realpath retorna o caminho real de um arquivo
  • $0 é este arquivo (o script)
  • s|old|new|substitua oldpornew
  • \(.*\)/salve os caracteres antes /para depois
  • \1 a parte salva
Zanna
fonte
2
+1 para uso $0e sedmagia. Mas a sedmágica mencionada é realmente desnecessária quando dirnameexistem ferramentas como a #
Sergiy Kolodyazhnyy 17/17/17
2
você já tem a resposta, use realpath: realpath "$( dirname $0 )"Eu pessoalmente usaria, readlinkmas sou eu:readlink -e $(dirname $0)
Sergiy Kolodyazhnyy 17/03
@ Berg: Não dirname "$(realpath "$0")"seria melhor? Geralmente, é necessário conhecer o diretório pai do arquivo referenciado em vez do diretório pai do link simbólico referente ao referido arquivo.
David Foerster
4
@Serg "$(dirname "$(realpath "$0")")"é a maneira mais direta. Citações dentro do $()trabalho normalmente.
DepressedDaniel
@DepressedDaniel Pesquisamos um pouco on-line, você está certo: $()ser um subshell permitirá cotações do lado de fora. Eu não diria que é como se simples, a menos que se percebe $()são todos subshells
Sergiy Kolodyazhnyy
5

se o script estiver no seu caminho, você pode usar algo como

$ myloc=$(dirname "$(which foo.sh)")
$ echo "$myloc"
/path/to/foo.sh

EDIT: depois de ler os comentários do Serg, essa pode ser uma solução genérica que funciona se o script está no seu caminho ou não.

myloc==$(dirname "$(realpath $0)")
dirname "$myloc"
Antonello Piemonte
fonte
whiché mais adequado para quando o script reside em um dos diretórios que fazem parte da PATHvariável. Use $0de dentro de um script, como mostra Zanna. Mas sua resposta é correta, já que você usa em dirnamevez de mexer com sed, portanto, +1 para isso #
Sergiy Kolodyazhnyy 17/17/17
5

A resposta aceita parece perfeita. Aqui está outra maneira de fazer isso:

cd "$(dirname "$0")"
/bin/pwd

/bin/pwdimprime o caminho real do diretório, em oposição ao pwdcomando interno.

serv-inc
fonte
0
wdir="$PWD"; [ "$PWD" = "/" ] && wdir=""
case "$0" in
  /*) scriptdir="${0}";;
  *) scriptdir="$wdir/${0#./}";;
esac
scriptdir="${scriptdir%/*}"
echo "$scriptdir"

É tomado como referência de kenorb e andro
Sem nome de diretório, readlink, caminho real, BASH_SOURCE
Todos são internos

HemanthJabalpuri
fonte