Ad esempio, controlla se $PWD
è una sottodirectory di / home. In altre parole, sto cercando un'operazione di stringa bash per verificare se una stringa inizia con un'altra.
Ad esempio, controlla se $PWD
è una sottodirectory di / home. In altre parole, sto cercando un'operazione di stringa bash per verificare se una stringa inizia con un'altra.
Risposte:
Se si desidera verificare in modo affidabile se una directory è una sottodirectory di un'altra, è necessario più di un semplice controllo prefisso stringa. La risposta di Gilles descrive in dettaglio come eseguire correttamente questo test.
Ma se vuoi un semplice controllo prefisso stringa (forse hai già normalizzato i tuoi percorsi?), Questo è buono:
test "${PWD##/home/}" != "${PWD}"
Se $PWD
inizia con "/ home /", viene rimosso nella parte sinistra, il che significa che non corrisponderà alla parte destra, quindi "! =" Restituisce true.
${PWD/#$HOME/\~}
"${PWD%%/subdir*}"
per rilevare se l'utente è attualmente in subdir
o in una sottodirectory di subdir
, poiché %% acquisisce dalla fine della stringa anziché dall'inizio. Questo dovrebbe essere utile a chiunque cerchi maggiori informazioni sulla sostituzione dei parametri: tldp.org/LDP/abs/html/parameter-substitution.html
Per verificare se una stringa è un prefisso di un'altra, in qualsiasi shell in stile Bourne:
case $PWD/ in
/home/*) echo "home sweet home";;
*) echo "away from home";;
esac
Lo stesso principio funziona per un suffisso o un test di sottostringa. Si noti che nei case
costrutti, diversamente dai nomi dei file, *
corrisponde a qualsiasi carattere, incluso un /
o un iniziale .
.
Nelle shell che implementano la [[ … ]]
sintassi (cioè bash, ksh e zsh), può essere usato per abbinare una stringa a uno schema. (Notare che il [
comando può solo testare le stringhe per l'uguaglianza.)
if [[ $PWD/ = /home/* ]]; then …
Se stai verificando specificamente se la directory corrente è sotto /home
, un semplice test di sottostringa non è sufficiente, a causa di collegamenti simbolici.
Se /home
è un file system a sé stante, verifica se la directory corrente ( .
) si trova su quel file system.
if [ "$(df -P . | awk 'NR==2 {print $6}')" = "/home" ]; then
echo 'The current directory is on the /home filesystem'
fi
Se si dispone di NetBSD, OpenBSD o GNU (ad esempio Linux) readlink
, è possibile utilizzare readlink -f
per rimuovere i collegamenti simbolici da un percorso.
case $(readlink -f .)/ in $(readlink -f /home)/*) …
Altrimenti, è possibile utilizzare pwd
per mostrare la directory corrente. Ma devi fare attenzione a non usare una shell incorporata se la shell tiene traccia dei cd
comandi e mantiene il nome che hai usato per raggiungere la directory piuttosto che la sua posizione “effettiva”.
case $(pwd -P 2>/dev/null || env PWD= pwd)/ in
"$(cd /home && { pwd -P 2>/dev/null || env PWD= pwd; })"/*) …
Versione grezza:
[ ${PWD:0:6} = "/home/" ]
Ha lo svantaggio di dover prima contare i personaggi e non si può sostituire /home/
con qualcosa di simile $1
.
modifica (grazie @Michael) per la generalizzazione da confrontare con $VAR
uno che puoi usare
[ "${PWD:0:${#VAR}}" = $VAR ]
${#var}
è la lunghezza di $var
, quindi puoi generalizzarlo come[ "${PWD:0:${#1}}" = "$1" ]
Non capisco bene la domanda, ma per trovare il genitore di $ PWD , fallo dirname $PWD
. Per trovare il genitore del genitore, esegui dirname $(dirname $PWD)
e così via ...
/
. Ok, potrei controllare ricorsivamente, ma non c'è qualcosa di più facile?
Utilizzando awk
:
echo $PWD | awk -v h="/home" '$0 ~ h {print "MATCH"}'
E 'un peccato che [
non abbia un'opzione per testare le STRING1 starts with STRING2
condizioni.
Puoi provare echo $PWD | grep '^$VAR'
, ma può fallire in modi interessanti quando VAR
contiene simboli speciali.
awk
La index
funzione dovrebbe essere in grado di fare il trucco. Ma tutto ciò sembra troppo pesante per una cosa così facile da testare.
Se viene trovata la parte cercata del percorso, "svuoto" la variabile:
[[ -z "${PWD//*\/home\/*/}" ]] && echo "toto"
[ "${PWD##$VAR}" != "$PWD" ]
E se questo fosse un [code-golf] ( stackoverflow.com/questions/tagged/code-golf)question mi avresti battuto di due caratteri ;-) Inoltre sembra più leggibile ...