xterm não muda de diretório quando é movido

4

Recentemente, fiquei muito frustrado com o xterm não se comportando como esperado. Isso é o que eu estava fazendo:

  1. xterm aberto
  2. execute os seguintes comandos:

    $ mkdir test_01
    $ cd test_01/
    $ echo 'a' > a
    $ cat a
    

    A saída será:

    a
    
  3. abra outro xterm (não feche o primeiro)

  4. execute os seguintes comandos:

    $ mv test_01/ test_01_old
    $ mkdir test_01
    $ cd test_01
    $ echo 'b' > a
    $ cat a
    

    A saída será:

    b
    
  5. agora no xterm original, execute o comando:

    $ cat a
    

    A saída será:

    a
    

Por que isso acontece? Neste estágio, ambos os xterms relatam o mesmo diretório com o comando pwd (que é /home/user_1/test_01 ).

    
por Valera Rozuvan 10.08.2012 / 09:52

1 resposta

12

Isso tem pouco a ver com o xterm. Você poderia fazer a mesma coisa com dois shells sem invocar o xterm. Por falar nisso, você poderia fazer isso com um shell (veja abaixo).

Cada processo tem um diretório de trabalho atual. Isso não é rastreado pelo nome, mas como um ponteiro (mais ou menos) para o diretório em si. (Não tenho certeza de como isso é representado internamente; pode ser algo como os números de dispositivos maiores e menores e o número de inode do diretório.)

O shell em execução no seu primeiro xterm possui test_01 como seu diretório atual. Esse diretório é então renomeado (por outro processo) de test_01 para test_01_old - mas ainda é o mesmo diretório, e o processo do shell ainda o tem como seu diretório atual.

O kernel não lembra o nome do diretório atual, mas sim o seu shell. Ele usa essas informações quando você executa o comando pwd interno. O shell em seu primeiro xterm não percebeu que o diretório foi renomeado, portanto, quando você digita pwd , ele imprime o caminho em cache.

Mas /bin/pwd é um comando externo e não tem acesso às informações em cache do shell. Ele funciona iniciando no diretório atual (cujo nome ele não sabe imediatamente), observando sua entrada .. e percorrendo a hierarquia de diretórios até chegar à raiz (ou seja, o diretório cujos pontos de entrada .. para si mesmo); em seguida, ele imprime os elementos do caminho na ordem inversa delimitada por / caracteres.

Por exemplo, eu fiz o seguinte no meu sistema (Ubuntu 12.04, bash 4.2.24):

$ pwd ; /bin/pwd
/home/kst
/home/kst
$ mkdir test_01
$ cd test_01
$ pwd ; /bin/pwd
/home/kst/test_01
/home/kst/test_01
$ mv /home/kst/test_01 /home/kst/test_01_old
$ pwd ; /bin/pwd
/home/kst/test_01
/home/kst/test_01_old
$ cd $(/bin/pwd)
$ pwd ; /bin/pwd
/home/kst/test_01_old
/home/kst/test_01_old
$ 

Como você pode ver, pwd e /bin/pwd são consistentes até que eu renomeie o diretório atual; então o pwd do shell imprime o que ele lembra do diretório atual. Mas quando eu faço cd $(/bin/pwd) , os dois estão em sincronia novamente.

    
por 10.08.2012 / 10:47