O que faz a saída pwd?

5

O comando pwd em um script de shell mostra o diretório em que o shell script está?

    
por mkdrive2 12.02.2016 / 03:32

5 respostas

19

Existem três "diretórios" independentes aqui:

  1. o diretório de trabalho atual do seu shell atual,
  2. o diretório de trabalho atual do script shell e
  3. o diretório que contém o script de shell.

Para demonstrar que eles são independentes, você pode escrever um script de shell, salvo em /tmp/pwd.sh, contendo:

#!/bin/sh
pwd
cd /var 
pwd

Você pode então alterar seu pwd (# 1 acima) para /:

cd /

e execute o script:

/tmp/pwd.sh

que começa demonstrando seu pwd existente (# 1), depois muda para / var e o mostra novamente (# 2). Nenhum desses pwd foi "/ tmp", o diretório que contém /tmp/pwd.sh (# 3).

    
por 12.02.2016 / 03:40
7

Diretório de trabalho presente (ou atual)

Does the command pwd in a shell script return the directory the shell script is in?

Não.

Em primeiro lugar, por definição, nenhum shell script ou comando shell retorna nada além de um status de saída numérico entre 0 e 255. Isso é axiomático, mas geralmente não é o que as pessoas querem dizer quando fazem esses tipos de perguntas.

Em segundo lugar, pwd é tanto um Bourne shell builtin e um sistema padrão binário. Qualquer um imprime o diretório de trabalho atual lógico ou físico , que geralmente é:

  1. Sua localização na estrutura de diretórios quando você chama um script ou binário.
  2. Seu local atual depois de alterar o diretório de trabalho com cd ou outros utilitários e builtins que modificam o diretório de trabalho atual, como pushd ou popd.

Se você quiser o diretório do script atual, use o utilitário dirname , conforme descrito na seção final abaixo.

Teste rápido de pwd

Como um teste rápido para ver o que pwd realmente imprime, você pode executar o seguinte:

# Create a shell script containing pwd.
cat <<-EOF > /tmp/test_pwd.sh
#!/bin/sh

pwd
EOF

# Make the script executable.
chmod 755 /tmp/test_pwd.sh

# Go somewhere on the filesystem, and call the test script.
cd /etc
/tmp/test_pwd.sh

Isso imprimirá /etc , não /tmp , porque seu diretório de trabalho atual é atualmente /etc . Esse é o comportamento esperado.

Obtendo o diretório contendo um script

Provavelmente você está fazendo esta pergunta porque deseja encontrar o diretório do script atual. No caso geral, o seguinte é a solução rápida e suja:

#!/usr/bin/env bash
echo $(dirname "$0")

Isso funciona porque $0 geralmente contém o nome de caminho usado para invocar o script que está sendo executado, e a expansão de shell usa o utilitário dirname para retornar o caminho, excluindo a parte do nome do arquivo. Você pode fazer algo semelhante, mas menos portável, com a expansão do parâmetro Bash "${0%/*}" .

Isso tudo é uma vasta simplificação, é claro. Leia o manual de Bash (especialmente as seções sobre parâmetros posicionais, parâmetros especiais e BASH_SOURCE ) e as man pages para readlink e realpath para obter uma compreensão mais completa de quais são os casos de borda, dos quais existem vários.

No entanto, no script do dia-a-dia, o componente de diretório de $0 é suficiente para dizer o que você deseja saber. Se você está fazendo algo complicado o suficiente, onde $0 não contém as informações que você realmente precisa, e você precisa de construções mais complicadas como:

echo $(dirname "$(realpath "$0")")

então provavelmente você está tornando sua vida mais difícil do que precisa ser.

    
por 12.02.2016 / 08:49
5

pwd retorna 0, a menos que seu diretório de trabalho atual não possa ser aberto.

mkdir /tmp/d; cd "$_"
pwd && pwd -P; echo "$?"
rmdir ../d
pwd && pwd -P; echo "$?"
/tmp/d
/tmp/d
0
/tmp/d
pwd: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
1
    
por 12.02.2016 / 07:36
4

Existe esse conceito chamado cwd que todo processo em execução controla.

Ou melhor redigido: o kernel mantém uma ideia do cwd de cada processo.

Que possa ser lido com (para um sistema com / proc):

readlink /proc/$PID_of_PROCESS/cwd

E para o shell em execução (do qual seu PID deve ser $$):

$ readlink /proc/$$/cwd

O shell controla as mesmas informações (mesmo que às vezes elas saiam de sincronia) na variável $ PWD e no comando pwd :

$ cd /tmp; echo "Present working directory: $PWD"
Present working directory: /tmp
$ cd /tmp; echo "Current working directory: $(pwd)"
Current working directory: /tmp

Portanto, o comando pwd apresenta o cwd de cada processo:

The place each process stands inside the directory tree.

Cada vez que um shell, script ou processo executa um cd , todas essas variáveis são atualizadas (exceto alguns casos de canto).

Um shell pode alterar seu pwd executando um cd /tmp , por exemplo.

Um script pode informar ao shell sob o qual ele está sendo executado para alterar também o pwd com um cd /tmp .

Ou algum outro processo c pode chamar o kernel para executar um equivalente a cd /tmp .

Em todos os casos, o kernel cwd e (se o processo for um shell), o pwd do shell é atualizado.

    
por 12.02.2016 / 05:42
1

Ele retorna o diretório de onde é chamado / executado em & não onde está o roteiro!

Aqui está o try.sh:

echo "The current working directory: $PWD"

Esta saída será mais clara:

[akarpe@ADM-PROD-OMNI ~]$ sh try.sh
The current working directory: /mnt/home/akarpe
[akarpe@ADM-PROD-OMNI ~]$ sh try/try.sh
The current working directory: /mnt/home/akarpe
[akarpe@ADM-PROD-OMNI ~]$ sh ./try.sh
The current working directory: /mnt/home/akarpe
[akarpe@ADM-PROD-OMNI ~]$ sh ./try/try.sh
The current working directory: /mnt/home/akarpe
[akarpe@ADM-PROD-OMNI ~]$ cd try
[akarpe@ADM-PROD-OMNI try]$ sh ./try.sh
The current working directory: /mnt/home/akarpe/try
[akarpe@ADM-PROD-OMNI try]$ sh ../try.sh
The current working directory: /mnt/home/akarpe/try
    
por 12.02.2016 / 03:42