Obtenha o caminho completo a partir do script Bash

2

Eu tenho um script bash que funciona com caminhos relativos. Ele precisa ter um diretório de trabalho que seja igual ao diretório em que o script está armazenado. Isso funciona bem, desde que eu inicie-o a partir do prompt, pois posso fazer o cd para o diretório do script primeiro. No entanto, quando eu crio um symlink para o script em /etc/cron.hourly, o script quebra.

Eu preciso de uma maneira de fazer o script bash mudar o diretório para o diretório em que o script está armazenado. No entanto, até agora não obtive sucesso. Existe uma maneira fácil de fazer isso, mesmo que o script seja chamado pelo cron através de um symlink?

    
por Magnus 09.10.2012 / 15:52

4 respostas

-1

Você deve ser capaz de fazer isso.

  • O parâmetro $ 0 se expande para o caminho completo (incluindo o nome) do script conforme foi chamado.
  • A função de shell integrada test (ou [] ) pode testar se um caminho é um link simbólico usando -L
  • ls -l , se aplicado a um symlink, fornecerá uma única linha de saída com o caminho verdadeiro como o campo final.

Isso é o suficiente para você descobrir a localização da fonte. Claro, isso pode ser um symlink, o que exigiria que você fizesse isso de forma recursiva ...

    
por 09.10.2012 / 16:07
1

Não me lembro de onde obtive isso, então posso atribuir corretamente, mas usei isso por um longo tempo para obter o caminho "canônico" para o script que estou executando. Por canônico, quero dizer caminho absoluto sem "." ou ".." nele.

CANON=$(cd -P -- "$(dirname -- "$0")" && printf '%s\n' "$(pwd -P)/$(basename -- "$0")")

Se eu precisar, usarei basename e dirname no $ CANON para obter esses valores.

    
por 09.10.2012 / 17:47
0

A variável $0 contém o nome do programa. Fazer

cd $(dirname $( readlink $0) )

para mudar para o diretório em que o programa reside.

Sim, $0 pode ser problemático , se usado em uma situação geral. Eu acho que usá-lo para o próprio trabalho em uma situação particular, onde a configuração está claramente definida, está bem.

Em particular, o script não deve usar seu diretório para trabalhar de qualquer forma, deve depender de uma variável de ambiente ou de um arquivo de configuração, então por que se preocupar com detalhes como "alguém pode ter movido o script desde que você o iniciou" ou como o ksh irá interpretá-lo (dado que sabemos que este é um script bash).

    
por 09.10.2012 / 15:59
0

O shell sempre conhece o caminho para o script em circunstâncias normais, porque é necessário lê-lo. Observe que há circunstâncias em que isso não é verdadeiro, por exemplo, com scripts setuid nos sistemas operacionais que os suportam (não no Linux) - mas scripts de shell setuid são uma má idéia de qualquer maneira. Mais importante ainda, o script pode ter sido movido entre o momento em que o shell foi aberto e a hora em que você tenta fazer alguma coisa com ele. Portanto, use somente o caminho para o script quando não houver preocupação de segurança ou confiabilidade ao fazer isso. Um pacote de software com uma estrutura conhecida é um caso de uso válido.

O caminho para o script que foi passado para o interpretador de shell está disponível no parâmetro especial $0 . Este pode ser um caminho relativo, então se você for usá-lo, faça isso antes de mudar para outro diretório. Você pode usá-lo se souber que o script não será movido nesse meio tempo.

Como $0 pode ser um link simbólico, você precisará obter o alvo. Não existe uma maneira POSIX para fazer isso, mas no Linux (GNU coreutils ou BusyBox) e no recente BSD você pode usar readlink -f para obter um .

script_path_in_package=$(readlink -f -- "$0")
script_directory=${script_path_in_package%/*}

Observe que isso restringe as maneiras pelas quais você pode estruturar seu pacote. Por exemplo, você não pode colocar o script em uma árvore de diretórios independente de arquitetura e vinculá-lo a cada árvore de diretórios específica da arquitetura.

    
por 09.10.2012 / 19:55

Tags