Como pwd e. determinar o caminho atual de forma diferente?

3

É principalmente porque pwd não é um builtin, enquanto . está embutido no shell bash?

Por exemplo, eles diferem no exemplo a seguir:

/tmp/ttt$ mv ../ttt ../tttt
/tmp/ttt$ pwd
/tmp/ttt
/tmp/ttt$ cd .
/tmp/tttt$
    
por Tim 31.07.2014 / 17:54

3 respostas

8

. não é um bash (ou qualquer outro shell) embutido. Cada diretório possui entradas . e .. . Você pode verificar por cd'ing para algum diretório arbitrário e fazendo ls -lia . Você verá . e .. entradas. Eu usei o sinalizador '-i' em ls para obter números de inode: observe-os para . e .. . Vá até um diretório, mas fazendo cd .. ou cd /something/soemthingelse/whatever . Do ls -lia novamente. Observe que o número de inode de . é idêntico ao de .. em sua primeira listagem. Todo diretório tem diretórios quando criado, chamado "." e "..". O "." entry tem o mesmo número de inode que o nome do diretório em seu diretório pai. A entrada ".." é sempre o diretório pai. Se você fizer ls -li / , verá que "." e ".." tem o mesmo valor.

Esta convenção elimina a necessidade de um código de caso especial para referenciar o diretório atual: ele é sempre chamado de ".". Elimina a necessidade de código de caso especial para "subir um diretório": é sempre "..". Os únicos casos especiais são o diretório raiz e os sistemas de arquivos montados em rede. A raiz do sistema de arquivos tem "." e ".." com o mesmo número de inode, não diferente. Os sistemas de arquivos montados em rede têm uma descontinuidade nos números de inode no ponto de montagem, e o comportamento depende do sistema de arquivos remoto e de qual protocolo é usado para montá-lo.

No que diz respeito à alteração no prompt, quando você invocou mv ../ttt ../tttt , você realmente renomeou o diretório de trabalho do seu shell. Você não chamou um comando shell que verifica o diretório de trabalho até que você tenha cd . , portanto, o pwd informará o nome antigo, /tmp/tt .

    
por 31.07.2014 / 19:24
5

Supondo que você esteja usando o Bash que tem pwd como um 1 , o que acontece é que o comando cd aciona o shell para atualizar as informações relativas ao diretório atual. Até você executar cd , o shell pensará que o diretório atual não foi alterado, portanto, ele não tenta obter seu novo caminho.

A propósito, para expandir um pouco a resposta do Gnouc, a Edição 6 do Especificações do Grupo Aberto sobre < a href="http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html"> variáveis de ambiente diz:

PWD [...] shall represent an absolute pathname of the current working directory. It shall not contain any filename components of dot or dot-dot. The value is set by the cd utility.

Por outro lado, se você executar o comando /bin/pwd externo, você obterá o novo nome do diretório atual. Por que isso acontece? O comando pwd de coreutils faz algumas verificações de sanidade da variável de ambiente PWD e não imprime se for inválido. Os detalhes podem ser encontrados no código fonte do logical_getcwd function (do coreutils versão 8.23).

Outro comando que você pode usar para obter o caminho canônico do diretório atual é readlink -f . 2 .

[ciupicri@host ttt]$ pwd
/tmp/ttt
[ciupicri@host ttt]$ mv ../ttt ../tttt
[ciupicri@host ttt]$ pwd
/tmp/ttt
[ciupicri@host ttt]$ /bin/pwd
/tmp/tttt
[ciupicri@host ttt]$ readlink -f .
/tmp/tttt

1 A execução de type pwd pode confirmar isso.

2 No readlink homem página: -f , --canonicalize canonicalize seguindo cada link simbólico em todos os componentes do nome dado recursivamente; todos, exceto o último componente, devem existir.

    
por 31.07.2014 / 18:20
3

pwd imprimirá o valor de $PWD se contiver um nome de caminho absoluto que não tenha ponto . ou ponto-ponto .. . De POSIX pwd definição:

-L
    If the PWD environment variable contains an absolute pathname of the 
    current directory that does not contain the filenames dot or dot-dot, 
    pwd shall write this pathname to standard output. Otherwise, if the PWD 
    environment variable contains a pathname of the current directory that 
    is longer than {PATH_MAX} bytes including the terminating null, and the 
    pathname does not contain any components that are dot or dot-dot, it is 
    unspecified whether pwd writes this pathname to standard output or 
    behaves as if the -P option had been specified. Otherwise, the -L option 
    shall behave as the -P option.

Por padrão, a opção pwd use -L irá imprimir o valor da corrente PWD , que é definida quando você usa cd . Quando você mv o diretório atual para o novo caminho, PWD ainda não mudará, assim você obterá o nome do caminho antigo.

Você pode ter algumas formas de obter o novo nome de caminho certo:

  • Usando -P option: pwd -P
  • Usando /proc : ls -l /proc/self/cwd

Nota

Como definição POSIX para a variável PWD , se um conjunto de aplicativos ou um valor não definido de PWD , os comportamentos de cd e pwd não são especificados.

% cuonglm at /tmp/ttt
% PWD=/home/cuonglm
% cuonglm at ~
% pwd
/tmp/ttt
% cuonglm at ~
% pwd -P
/tmp/ttt
    
por 31.07.2014 / 18:51

Tags