Zde jsou ve hře tři nezávislé "adresáře":
- aktuální pracovní adresář vašeho aktuálního shellu,
- aktuální pracovní adresář skriptu shellu a
- adresář obsahující skript shellu.
Chcete-li demonstrovat, že jsou nezávislé, můžete napsat skript shellu uložený v /tmp/pwd.sh obsahující:
#!/bin/sh
pwd
cd /var
pwd
Poté můžete změnit své pwd (č. 1 výše) na /:
cd /
a spusťte skript:
/tmp/pwd.sh
což začíná ukázkou vašeho stávajícího pwd (#1), poté jej změní na /var a znovu ho zobrazí (#2). Ani jeden z těchto pwd
's byly "/tmp", adresář, který obsahuje /tmp/pwd.sh (#3).
Současný (nebo aktuální) pracovní adresář
Vrací příkaz pwd ve skriptu shellu adresář, ve kterém je skript shellu?
Ne.
Za prvé, podle definice žádný skript nebo příkaz shellu nevrací nic jiného než číselný stav ukončení mezi 0 - 255. To je axiomatické, ale obecně to není to, co lidé myslí, když kladou tyto typy otázek.
Za druhé, pwd
je jak vestavěný Bourne shell, tak standardní binární systém. Buď jeden vytiskne logický nebo fyzický aktuální pracovní adresář , což je obecně:
- Vaše umístění v adresářové struktuře, když voláte skript nebo binární soubor.
- Vaše aktuální poloha po změně pracovního adresáře pomocí cd nebo jiné nástroje a vestavěné moduly, které upravují aktuální pracovní adresář, jako je pushd nebo popd.
Pokud chcete adresář aktuálního skriptu, použijte dirname
nástroj, jak je popsáno v poslední části níže.
Rychlý test pwd
Jako rychlý test zjistit, co pwd skutečně tiskne, můžete spustit následující:
# 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
Tím se vytiskne /etc
, nikoli /tmp
, protože váš aktuální pracovní adresář je aktuálně /etc
. Toto je očekávané chování.
Získání adresáře obsahujícího skript
Tuto otázku si pravděpodobně kladete, protože chcete najít adresář aktuálního skriptu. V obecném případě je toto rychlé a špinavé řešení:
#!/usr/bin/env bash
echo $(dirname "$0")
To funguje, protože $0
obecně obsahuje cestu použitou k vyvolání spouštěného skriptu a rozšíření shellu používá dirname
obslužný program pro vrácení cesty bez části názvu souboru. Něco podobného, ale méně přenosného, můžete udělat s rozšířením parametru Bash "${0%/*}"
.
To vše je samozřejmě obrovské přílišné zjednodušení. Přečtěte si prosím příručku Bash (zejména části o pozičních parametrech, speciálních parametrech a BASH_SOURCE ) a manuálové stránky pro readlink
a realpath
abyste lépe porozuměli tomu, co jsou okrajové případy, kterých je několik.
Nicméně v každodenním skriptování je to adresářová komponenta $0
stačí k tomu, abyste řekli, co chcete vědět. Pokud děláte něco dostatečně složitého, kde $0
neobsahuje informace, které skutečně potřebujete, a vyžadujete složitější konstrukce jako:
echo $(dirname "$(realpath "$0")")
pak si pravděpodobně děláte život těžší, než je nutné.
pwd
vrátí 0, pokud nelze otevřít jeho aktuální pracovní adresář.
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