
O comando pwd
em um script de shell exibe o diretório em que o script de shell está?
Responder1
Existem três "diretórios" independentes em jogo aqui:
- o diretório de trabalho atual do seu shell atual,
- o diretório de trabalho atual do script shell e
- o diretório que contém o script de shell.
Para demonstrar que eles são independentes, você pode escrever um script 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 (nº 1), depois altera-o para /var e mostra-o novamente (nº 2). Nenhum desses pwd
era "/tmp", o diretório que contém /tmp/pwd.sh (#3).
Responder2
Diretório de trabalho atual (ou atual)
O comando pwd em um script de shell retorna o diretório em que o script de shell está?
Não.
Em primeiro lugar, por definição, nenhum script ou comando shell retorna algo 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 esse tipo de pergunta.
Em segundo lugar, pwd
é ao mesmo tempo umShell Bourne integradoe um sistema binário padrão. Qualquer umestampaso lógico ou físicodiretório de trabalho atual, que geralmente é:
- Sua localização na estrutura de diretórios quando você chama um script ou binário.
- Sua localização atual após alterar o diretório de trabalho comcdou outros utilitários e componentes internos que modificam o diretório de trabalho atual, como pushd ou popd.
Se você deseja o diretório do script atual, use o dirname
utilitário conforme descrito na seção final abaixo.
Teste rápido depwd
Como um teste rápido para ver o quesenharealmente 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
Isto irá imprimir /etc
, não /tmp
, porque seu diretório de trabalho atual é atualmente /etc
. Este é o comportamento esperado.
Obtendo o diretório que contém um script
Você provavelmente 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 do caminho usado para invocar o script que está sendo executado, e a expansão do shell usa o dirname
utilitário para retornar o caminho, excluindo a parte do nome do arquivo. Você pode fazer algo semelhante, mas de forma menos portável, com a expansão do parâmetro Bash "${0%/*}"
.
Tudo isso é uma grande simplificação, é claro. Por favor leia oManual do Bash(especialmente as seções sobre parâmetros posicionais, parâmetros especiais eBASH_SOURCE) e as páginas de manual para readlink
obter realpath
uma compreensão mais completa de quais são os casos extremos, dos quais existem vários.
No entanto, nos scripts do dia-a-dia, o componente de diretório $0
é suficiente para informar o que você deseja saber. Se você estiver fazendo algo complicado o suficiente, $0
não contém as informações que realmente precisa e 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.
Responder3
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
Responder4
Ele retorna o diretório de onde é chamado/executado e não onde o script está!
Aqui está try.sh :
echo "The current working directory: $PWD"
Esta saída deixará mais claro:
[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