Ci sono tre "directory" indipendenti in gioco qui:
- l'attuale directory di lavoro della tua shell corrente,
- la directory di lavoro corrente dello script della shell e
- la directory contenente lo script della shell.
Per dimostrare che sono indipendenti, puoi scrivere uno script di shell, salvato in /tmp/pwd.sh, contenente:
#!/bin/sh
pwd
cd /var
pwd
Puoi quindi cambiare il tuo pwd (n. 1 sopra) in /:
cd /
ed eseguire lo script:
/tmp/pwd.sh
che inizia dimostrando il tuo pwd esistente (#1), quindi lo cambia in /var e lo mostra di nuovo (#2). Nessuno di questi pwd
erano "/tmp", la directory che contiene /tmp/pwd.sh (#3).
Directory di lavoro attuale (o attuale)
Il comando pwd in uno script di shell restituisce la directory in cui si trova lo script di shell?
No.
In primo luogo, per definizione, nessuno script di shell o comando di shell restituisce qualcosa di diverso da uno stato di uscita numerico compreso tra 0 e 255. Questo è assiomatico, ma generalmente non è ciò che le persone intendono quando fanno questo tipo di domande.
In secondo luogo, pwd
è sia un built-in della shell Bourne che un binario di sistema standard. Uno dei due stampa la directory di lavoro corrente logica o fisica , che generalmente è:
- La tua posizione nella struttura della directory quando chiami uno script o un binario.
- La tua posizione attuale dopo aver cambiato la directory di lavoro con cd o altre utility e builtin che modificano la directory di lavoro corrente come pushd o popd.
Se vuoi la directory dello script corrente, usa dirname
utility come descritto nella sezione finale di seguito.
Test rapido di pwd
Come rapido test per vedere cosa pwd stampa davvero, puoi eseguire quanto segue:
# 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
Questo stamperà /etc
, non /tmp
, perché la tua attuale directory di lavoro è attualmente /etc
. Questo è il comportamento previsto.
Ottenere la directory contenente uno script
Probabilmente stai facendo questa domanda perché vuoi trovare la directory dello script corrente. Nel caso generale, la seguente è la soluzione veloce e sporca:
#!/usr/bin/env bash
echo $(dirname "$0")
Funziona perché $0
generalmente contiene il percorso utilizzato per richiamare lo script in esecuzione e l'espansione della shell utilizza dirname
utility per restituire il percorso escludendo la parte del nome file. Puoi fare qualcosa di simile, ma meno portabile, con l'espansione del parametro Bash "${0%/*}"
.
Questa è tutta una semplificazione eccessiva, ovviamente. Si prega di leggere il manuale di Bash (in particolare le sezioni sui parametri posizionali, parametri speciali e BASH_SOURCE ) e le pagine man per readlink
e realpath
per avere una comprensione più completa di cosa sono i casi limite, di cui ce ne sono diversi.
Tuttavia, nello scripting quotidiano, il componente directory di $0
è sufficiente per dirti quello che vuoi sapere. Se stai facendo qualcosa di abbastanza complicato dove $0
non contiene le informazioni di cui hai effettivamente bisogno e hai bisogno di costrutti più complicati come:
echo $(dirname "$(realpath "$0")")
allora probabilmente stai rendendo la tua vita più difficile di quanto dovrebbe essere.
pwd
restituisce 0 a meno che la sua directory di lavoro corrente non possa essere aperta.
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