Como é .. (ponto ponto) resolvido no bash quando cwd é um symlink para um diretório [duplicado]

4

Considere a seguinte estrutura de pastas:

.
├── test1
│   ├── nested1
│   ├── testfile11
│   └── testfile12
└── test2
    ├── nested1 -> /path/to/dir/test1/nested1
    └── testfile21

test2/nested1 é um link simbólico para o diretório test1/nested1 . Eu esperaria, se fosse o cwd, .. resolveria para test2 . No entanto, notei essa inconsistência:

$ cd test2/nested1/
$ ls ..
nested1  testfile11  testfile12
$ cd ..
$ ls
nested1  testfile21

touch também se comporta como ls , criando um arquivo em test1 .

Por que .. como um argumento para cd se refere ao pai do symlink, enquanto para (all?) outros se refere ao pai do diretório vinculado? Existe alguma maneira simples de forçá-lo a se referir a caminhos relativos ao symlink? Ou seja o "oposto" de readlink ?

# fictional command
ls $(linkpath ..)

EDIT: Usando o bash

    
por erich2k8 01.08.2018 / 04:26

3 respostas

2

Os comandos cd e pwd têm dois modos operacionais.

  • -L modo lógico: links simbólicos não são resolvidos

  • -P modo físico: os links simbólicos são resolvidos antes de executar a operação

O importante é saber que cd .. não chama o syscall chdir("..") , mas encurta a variável $PWD do shell e, em seguida, passa para o caminho absoluto.

Se você estiver no modo físico, isso é idêntico a chamar chdir("..") , mas quando no modo lógico, isso é diferente.

O principal problema aqui: POSIX decidiu usar o modo lógico menos seguro como padrão.

Se você chamar cd -P em vez de apenas cd , depois de uma operação chdir() , o valor de retorno de getcwd() será colocado na variável $PWD e um cd .. a seguir o levará a o diretório que está fisicamente acima do diretório atual.

Então, por que o padrão POSIX é menos seguro?

Se você cruzou um symlink no modo padrão POSIX e faça o seguinte:

ls ../*.c
cd ..
rm *.c

você provavelmente removerá arquivos diferentes daqueles que foram listados pelo comando ls antes.

Se você gosta do modo físico mais seguro, configure os seguintes alias:

alias cd='cd -P'
alias pwd='pwd -P'

Visto que ao usar mais de uma opção de -L e -P a última opção vence, você ainda poderá obter o outro comportamento.

Histórico:

O Bourne Shell e o ksh88 obtiveram o código de acompanhamento de diretórios ao mesmo tempo.

O Bourne Shell obteve o comportamento físico mais seguro, enquanto o ksh88, ao mesmo tempo, obteve o modo lógico menos seguro como padrão e as opções -L e -P . Pode ser que o ksh88 tenha usado o comportamento do csh como referência.

O POSIX assumiu o comportamento do ksh88 sem discutir se esta é uma boa decisão.

BTW: alguns shells não conseguem rastrear os valores $PWD que são maiores que PATH_MAX e deixam você louco quando você entra em um diretório com um caminho absoluto maior que PATH_MAX . dash é uma casca com defeito.

    
por 01.08.2018 / 09:13
2

Um papel importante para ler é o link onde Rob Pike fala sobre esse assunto.

Você também precisa especificar o seu shell, por exemplo, o bash rastreia a idéia do diretório atual e se você diz cd .. ele apenas corta o último componente e muda lá, em vez de realmente emitir uma chamada de sistema chdir("..") .

Desculpe no meu telefone no momento, vai editar depois ...

    
por 01.08.2018 / 04:56
0

Você pode querer dar -p a try, que seguirá a estrutura do diretório físico sem seguir os links simbólicos

link

    
por 01.08.2018 / 05:10