Como Resolver Links Simbólicos em um Script Shell

Trabalhar com links simbólicos (ou symlinks) em sistemas do tipo Unix pode ser complicado, especialmente quando você deseja descobrir o caminho real que um symlink aponta. Se você está escrevendo um script shell e precisa determinar o caminho completo de um alvo após resolver quaisquer symlinks intermediários, você está no lugar certo. Neste post do blog, vamos detalhar como conseguir isso de forma eficiente.

Entendendo o Problema

Imagine que você tem uma situação onde há um link simbólico foo que aponta para outro diretório bar. Quando você executa comandos como cd foo e pwd, seu shell pode não revelar claramente a estrutura subjacente, dificultando a derivação do caminho completo para o alvo.

Por exemplo:

ls -ld foo bar
drwxr-xr-x   2 greg  greg  68 Aug 11 22:36 bar
lrwxr-xr-x   1 greg  greg   3 Aug 11 22:36 foo -> bar

Se você executar:

cd foo
pwd

A saída seria simplesmente /Users/greg/tmp/foo, o que realmente não ajuda se seu objetivo é descobrir o caminho real que foo aponta, que é /Users/greg/tmp/bar.

A Solução

Felizmente, existem comandos internos que podem ajudar você a resolver symlinks em um script shell sem precisar se aprofundar na programação em C. Veja como fazê-lo:

Usando o Comando pwd

O comando pwd -P é usado para imprimir o diretório de trabalho atual, resolvendo todos os symlinks para fornecer o caminho absoluto do alvo. Quando você executar:

pwd -P

Ele retornará o caminho completo após resolver quaisquer symlinks.

Usando getcwd

Outra maneira de realizar isso é utilizando a função getcwd da biblioteca unistd.h em C. No entanto, se você estiver fazendo scripts, pode depender de comandos shell em vez disso. É uma boa prática saber que getcwd tem um comportamento semelhante ao de pwd -P.

Construindo a Função Resolve

Você pode encapsular esses comandos em uma função para facilitar seu trabalho. Aqui está um exemplo de uma simples função resolve em um shell Bash:

resolve() {
    # Use o caminho fornecido e resolva-o
    local target=$1
    # `readlink -f` segue symlinks, retornando o caminho completo
    local full_path=$(readlink -f "$target")
    echo "$full_path"
}

Exemplo de Uso

Agora, simplesmente chame a função com:

resolve "foo"

Isso retornará:

/Users/greg/tmp/bar

Esse padrão permite que você acesse o caminho completo de qualquer symlink que você encontrou em seu ambiente de script shell.

Bônus: Resolvendo Caminhos de Diretório Pessoal

Se você também deseja resolver diretórios pessoais usando a notação de til (como ~username), o Bash expande automaticamente esses caminhos em um script shell, portanto você pode combinar isso com sua função resolve de forma tranquila.

Conclusão

Resolver links simbólicos em scripts shell não precisa ser complicado. Ao utilizar o comando pwd -P ou criar uma função auxiliar como resolve que use readlink, você pode efetivamente determinar o caminho completo do seu alvo. Essa habilidade é essencial para qualquer pessoa que trabalhe em um ambiente do tipo Unix e torna seus scripts muito mais robustos e informativos.

Lembre-se, gerenciar symlinks corretamente pode economizar tempo e confusão ao navegar por estruturas de diretório ou escrever scripts shell complexos.