Como recuperar o nome do arquivo absoluto em um script de shell no Mac OS X?


19

Eu gostaria de recuperar o nome absoluto do arquivo de script atualmente executado. Os links também devem ser resolvidos.

No Linux, isso parece ser feito assim:

$(readlink -mn "$0")

mas readlinkparece funcionar de maneira muito diferente no Mac OS X.

Eu li que isso é feito usando

$(realpath $0)

no BSD, mas isso também não funciona. O Mac OS X não possui realpath.

Qualquer ideia?


1
Veja esta pergunta no SO: stackoverflow.com/questions/799679/…
Telêmaco


Respostas:


19

Eu trapaceio e uso o perl para isso:

#!/bin/bash
dirname=`perl -e 'use Cwd "abs_path";print abs_path(shift)' $0`
echo $dirname

Você pensaria que eu escreveria o script inteiro em perl, e geralmente escrevo, mas nem sempre.


Isso funciona, muito obrigado. Vou te dar uma votação o mais rápido possível. Alguém tem uma maneira "pura casca" de fazer isso?
Huxi

1
Receio que isso seja o melhor possível. (Dada a muitos múltiplo-line "puro shell" hacks pode-se encontrar no Google.)
Arjan

outra possibilidade (embora feia) é percorrer o caminho '..', memorizar (através de recursão ou matriz) até '..' retornar o mesmo arquivo que você tinha (por exemplo: você está no topo) e voltar a montar o caminho que você segue. Eu vi o software de backup Networker da Legato fazendo isso durante o strace como um método para obter um caminho 'verdadeiro' (mas talvez não absoluto). Mas seria muito mais código do que o acima.
21700 ericslaw

Não sei por que alguém modificou o código para usar $ 1 em vez de $ 0. $ 1 não é o primeiro argumento para o script bash? Eu queria o caminho para o script bash em execução, não é o primeiro argumento.
22613 Ericslaw

27
#!/usr/bin/env bash
scriptDir="$(cd "$(dirname "$0")" && pwd -P)"

Também funciona no MacOSX.
Alexar

1
Isso é super! Existem muitas outras respostas complicadas demais por aí.
Jason S

3
Isso só funciona para arquivos em um diretório link simbólico, não para arquivos simbolicamente em geral
Gerhard Burger

1
Também é útil unset -v CDPATHantes do CD, pois o CD pode causar uma saída indesejada se CDPATH estiver definido.
Phile binário 12/04

Para lidar com pelo menos uma única camada de link simbólico do arquivo, você pode também teste de uma maneira compatível com readlink (macs não tem -f): scriptDir=$(unset -v CDPATH; cd "$(dirname "$(readlink "$BASH_SOURCE" || echo "$BASH_SOURCE)")" && pwd -P)
Binary Phile

0

Ele lida com combinações de links simbólicos e funciona em arquivos e pastas:

#!/usr/bin/env bash
realpath()
{
    if ! pushd $1 &> /dev/null; then 
        pushd ${1##*/} &> /dev/null
        echo $( pwd -P )/${1%/*}
    else
        pwd -P
    fi
    popd > /dev/null
}

Mas não suporta realpath - relativo a. Isso exigiria a conversão descrita aqui .


0

Outra abordagem:

# Install.
brew install coreutils

# Use the GNU variant.
grealpath --help
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.