Cosa fa $ {0% / *} negli script di shell?


17

Scusami se questa è una domanda stupida, ma l'ho cercato senza successo.

Cosa fa esattamente la seconda riga?

#!/bin/sh
cd ${0%/*} || exit 1

So che il primo è lo shebang, il secondo cerca di cambiare directory ma la parte confusa è ${0%/*}.

Potete per favore spiegarmi quella seconda riga?


2
Come spiegato da Andrea in una risposta, $ {0% / *} si traduce nel percorso della directory preceduto dal nome dello script mentre lo invoca. Un'alternativa è usare il dirnamecomando incorporato come$(dirname $0)
impara sempre il

@alwayslearning: In quale versione shell e shell stai utilizzando quella dirnameintegrata? Certamente non è in Bash v4.3.11 che è la shell predefinita in Ubuntu Trusty.
David Foerster,

Mi scuso per la confusione, dirnameho appena verificato che non è una shell integrata.
impara sempre l'

Risposte:


27

${0}è il primo argomento dello script, ovvero il nome o il percorso dello script. Se si avvia lo script come path/to/script.sh, allora ${0}sarà esattamente quella stringa: path/to/script.sh.

La %/*parte modifica il valore di ${0}. Significa: prendere tutti i caratteri fino a quando non viene /seguito da un nome file. Nell'esempio sopra, ${0%/*}sarà path/to.

Puoi vederlo in azione sulla tua shell:

$ x=path/to/script.sh
$ echo "${x%/*}"
path/to

Sh supporta molti altri tipi di "sostituzione dei parametri". Ecco, ad esempio, come prendere il nome del file anziché il percorso:

$ echo "${x##*/}"
script.sh

In generale, %e %%rimuovere i suffissi, mentre #e ##rimuovere i prefissi. Puoi leggere di più sulla sostituzione dei parametri .


2
Questa "|| uscita 1" sembra essere inutile: se sarà ora cambiare dir $? è uguale a 1.
Josef Klimuk il

2
Sarebbe bello menzionare che il costrutto è documentato come "Rimuovi modello di prefisso / suffisso corrispondente" nel manuale. Anche un bel modo per ricordare quale è che è # è il turno 3 (a sinistra di $),% è il turno 5 (a destra di $), almeno sulla tastiera americana.
chexum,

1
@JosefKlimuk: || exit 1 potrebbe essere necessario perché cdpotrebbe uscire con stato 2, non 1, in caso di errore. Tuttavia, sono d'accordo che non sia molto utile (di solito i programmi non si preoccupano di specifici stati di uscita). Probabilmente fa parte di una sceneggiatura più ampia?
Andrea Corbellini,

1
@AndreaCorbellini Sicuramente vero. Praticamente l'unico modo in cui può essere utile è come parte di uno script più ampio. Uno script che modifica semplicemente la directory corrente non ha alcun effetto, poiché influisce solo sulla shell che esegue quel singolo script. Il processo genitore non lo vede mai.
hvd,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.