Tenha em atenção que $0
pode ser um caminho relativo, pelo que chamar cd
duas vezes pode não funcionar. Além disso, extrair a parte do diretório $0
funciona nos casos mais . A maioria não é o mesmo que todos . Alguns casos em que pode falhar incluem:
- O script não é invocado pela execução de seu caminho, mas chamando um shell, por exemplo
bash myscript
(que faz uma pesquisaPATH
). - O script é movido durante sua execução.
Contanto que você documente que o seu script deve ser chamado sem travessuras, pegar a parte do diretório $0
é ok.
Você precisa ser um pouco cuidadoso; é possível que $0
não contenha uma barra, se ela foi encontrada por meio de uma entrada PATH
vazia ou, com algumas conchas, uma entrada PATH
para .
. Vale a pena dar suporte a este caso, e isso significa que você precisa tomar precauções com ${0%/*}
.
A abordagem dirname
também não é totalmente direta. A substituição do comando consome novas linhas no final. E com ambas as abordagens, você precisa tomar cuidado para que a string comece com -
e seja interpretada como uma opção; passe --
para terminar a lista de opções de um comando.
case "$0" in
*/*) cd -- "${0%/*}";;
*) cd -- "$0";;
esac
ou
cd -- "$(dirname -- "$0"; echo /)"
Em relação às aspas duplas, você está fazendo a pergunta errada. "$0"
é o valor do parâmetro 0
. $0
, sem aspas, é o valor do parâmetro 0
split em caracteres em IFS
com cada elemento, em seguida, interpretado como um padrão glob e substituído por arquivos correspondentes, se houver algum (essa última parte apenas se a globulação não estiver desativada) . Você não quer dizer o valor do parâmetro 0
dividido em caracteres em IFS
com cada elemento, então interpretado como um padrão glob e substituído por arquivos correspondentes, se houver algum (essa última parte somente se a globulação não estiver desativada) , você? Você quer dizer o valor do parâmetro 0
. Então escreva o que você quer dizer: "$0"
.
A única razão pela qual seus testes não engasgaram é que você não tentou com nomes problemáticos e você testou com um shell específico que acontece para reparar seu erro neste cenário específico. Com um nome de diretório como foo bar
, você acaba passando dois argumentos foo
e bar
para o comando cd
; O comando cd
do bash interpreta isso como “mude para o diretório obtido pela concatenação de foo
, um espaço e bar
”, por isso, é feito o retorno do nome correto. Um shell diferente pode interpretar isso como "reclamar sobre um argumento falso", "alterar para o diretório foo
" ou "alterar para o diretório obtido substituindo foo
por bar
no diretório de trabalho atual". Com o bash, seu script falharia se o nome continha dois espaços consecutivos, por exemplo.