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.