Como eu posso criar um symlink relativo dado um caminho relativo?

1

Eu gostaria de encontrar programaticamente a profundidade do diretório de um caminho relativo. Por exemplo, a profundidade de test/dir/hello é 3

Mais especificamente, gostaria da profundidade do diretório para poder criar um link simbólico para um arquivo localizado no diretório pai.

Eu tenho os dois parâmetros a seguir: ${current_path} e ${parent_file_to_lunk}

Como posso determinar a profundidade do diretório em ${current_path} para que eu possa criar um symlnk relativo para ${parent_file_to_lunk} ?

Algo parecido com isso, mas com tantos ../ quanto a profundidade do diretório:

cd ${current_path} ; ln -s ../$parent_file_to_link}
    
por Kostas 19.03.2015 / 14:13

3 respostas

1

Tente

parent_path=$(echo "$current_path"/ | sed -e "s|[^/]||g" -e "s|/|../|g")
cd "${current_path}" ; ln -s "${parent_path}${parent_file_to_link}"

Isso funciona simplesmente contando as barras em "${current_path}" . A profundidade desejada é mais uma que o número de barras (por exemplo, a profundidade de test/dir/hello , que contém duas barras, é 3), então simplesmente adicionamos uma barra: echo "$current_path"/ . Pipe em sed . Como estamos manipulando barras, é mais fácil usar um caractere diferente de / como o delimitador do comando sed s s ; Eu gosto de usar a barra vertical ( | ). s|[^/]||g encontra todos os caracteres que não são slash e substitui-os por nada. Em outras palavras, ele exclui todos os caracteres, exceto as barras. Então, para o valor "${current_path}" de test/dir/hello , nós echo 'd test/dir/hello/ e, em seguida, reduzimos para /// . Então s|/|../|g" muda cada / para ../ , então acabamos com ../../../ .

Nota: isso pressupõe que "${current_path}" não tem nenhum excesso (desnecessário) barras nele. Por exemplo, test/dir//hello e test/dir/hello/ são logicamente equivalentes a test/dir/hello , mas eles contêm um número enganoso de caracteres slash, o que irá corromper este processo.

P.S. Sempre cite todas as variáveis da shell, a menos que você tenha uma razão para não e você tem certeza de que sabe o que está fazendo. Usando chaves (como em ${variable_name} ) não é o equivalente a citar.

    
por 20.03.2015 / 06:23
0

algo como isso deve funcionar

file="/var/log/dmesg"
ln -s $file $(dirname $file)/../
    
por 19.03.2015 / 14:41
0

Supondo que você queira criar um:

/home/kostas/test/dir/hello/link -> /home/kostas/file/to/link

symlink (assumindo que /home/kostas é seu diretório atual), mas usando um link relativo, isto é:

/home/kostas/test/dir/hello/link -> ../../../file/to/link

Então você poderia fazer (com GNU ln ):

$ current_path=test/dir/hello
$ parent_file_to_lunk=file/to/link
$ ln -rsvt "$current_path/" "$parent_file_to_lunk"
‘test/dir/hello/link’ -> ‘../../../file/to/link’

Sem GNU ln , mas com GNU bash -O extglob ou zsh -o kshglob ou ksh93 :

$ ln -s "${current_path//+([^\/])/..}/$parent_file_to_lunk" "$current_path/"

(observe que os componentes de $current_path não são links próprios)

    
por 20.03.2015 / 15:31