Eu tenho um arquivo de script bash, que é colocado em algum diretório adicionado ao $ PATH para que eu possa chamar o script de qualquer diretório.
Há outro arquivo de texto no mesmo diretório que o script. Gostaria de saber como se referir ao arquivo de texto no script?
Por exemplo, se o script for apenas para gerar o conteúdo do arquivo de texto, cat textfile
não funcionará, pois ao chamar o script de um diretório diferente, o arquivo de texto não será encontrado.
Respostas:
Eles devem funcionar da mesma forma, desde que não haja links simbólicos (na expansão do caminho ou no próprio script):
MYDIR="$(dirname "$(realpath "$0")")"
MYDIR="$(dirname "$(which "$0")")"
Uma versão em duas etapas de qualquer uma das opções acima:
MYSELF="$(realpath "$0")"
MYDIR="${MYSELF%/*}"
Se houver um link simbólico no caminho para o seu script,
which
você fornecerá uma resposta que não incluirá a resolução desse link. Serealpath
não estiver instalado por padrão no seu sistema, você pode encontrá-lo aqui .[EDIT]: Como parece que
realpath
não tem vantagem sobre oreadlink -f
sugerido por Caleb , provavelmente é melhor usar o último. Meus testes de tempo indicam que é realmente mais rápido.fonte
realpath
vem no seu sistema. (Para outros que não tem isso, você pode usarreadlink -f
realpath
data de antesreadlink -f
(e até mesmo doreadlink
IIRC) estava no coreutils do GNU (havia várias ferramentas semelhantes por aí.readlink -f
eventualmente se tornou o padrão de fato);realpath
é mantido apenas para compatibilidade com scripts que ainda o utilizam.$(dirname "$(which "$0")")
mais de$(dirname $0)
onde owhich
não está mais presente? Não é o mesmo?readlink -f
parece não funcionar no Mac OS X 10.11.6, masrealpath
funciona imediatamente .Meus sistemas não têm
realpath
como sugerido por rozcietrzewiacz .Você pode fazer isso usando o
readlink
comando A vantagem de usar isso sobre a análisewhich
ou outras soluções é que, mesmo que uma parte do caminho ou o nome do arquivo executado fosse um link simbólico, você seria capaz de encontrar o diretório onde estava o arquivo real.Seu arquivo de texto pode ser lido em uma variável como esta:
fonte
which
sugestão. A solução normal para isso envolve apenasdirname
ou uma combinação decd
epwd
em um subshell. O Readlink tem a vantagem aqui.realpath
parece ser apenas um invólucro dereadlink -f
qualquer maneira.realpath
é diferentereadlink -f
. Só posso ver que me dá os mesmos resultados (em oposição awhich
).readlink -f
(do GNU coreutils) NÃO requer que o último elemento do caminho exista, requerreadlink -e
, mas não é suportado porbusybox readlink
, o que imita o comportamento de-e
suas-f
opções.$0
no script, será o caminho completo para o script edirname
seguirá um caminho completo e fornecerá apenas o diretório, para que você possa fazer isso no arquivo de texto cat:fonte
realpath $0
, você está errado ao dizer que "$0
no script será o caminho completo para o script".$0
é o comando como foi executado, o que pode ser por exemplo../script.sh
.$(dirname "$0")
retorna o caminho relativo para o script, como parte do comando chamado - não o caminho absoluto. Isso pode causar problemas nos scripts que alteram os diretórios durante a execução.Você pode colocar isso na parte superior do seu script:
Fonte: http://mywiki.wooledge.org/BashFAQ/028
fonte
Eu estava tentando isso e o caminho real não funcionou para mim. A solução que eu usei é:
O que funcionou bem até agora. Gostaria de saber se existem problemas em potencial com a abordagem.
fonte
SCRIPT_DIR="$( cd "$(dirname "$( readlink -f ${BASH_SOURCE[0]} )")" >/dev/null 2>&1 && pwd)"
Eu uso:
Que é POSIX e deve funcionar, desde que o nome do diretório
$0
não termine com caracteres de nova linha, não esteja-
e$CDPATH
não esteja definido (e possivelmente alguns outros casos de canto se o script não foi pesquisado$PATH
).fonte
Eu sempre uso
which
para encontrar o caminho completo de um executável do PATH. Por exemplo:which python
Se você combinar isso com o
dirname
comando, obterá:fonte