Par exemple, vérifiez si $PWD
est un sous-répertoire de / home. En d'autres termes, je recherche une opération de chaîne bash pour vérifier si une chaîne commence par une autre.
Par exemple, vérifiez si $PWD
est un sous-répertoire de / home. En d'autres termes, je recherche une opération de chaîne bash pour vérifier si une chaîne commence par une autre.
Réponses:
Si vous voulez tester de manière fiable si un répertoire est un sous-répertoire d'un autre, vous aurez besoin de plus qu'une simple vérification de préfixe de chaîne. La réponse de Gilles décrit en détail comment faire correctement ce test.
Mais si vous voulez une simple vérification du préfixe de chaîne (peut-être que vous avez déjà normalisé vos chemins?), C'est une bonne:
test "${PWD##/home/}" != "${PWD}"
Si $PWD
commence par "/ home /", il est supprimé du côté gauche, ce qui signifie qu'il ne correspond pas au côté droit, donc "! =" Renvoie true.
${PWD/#$HOME/\~}
"${PWD%%/subdir*}"
de détecter si l'utilisateur se trouve actuellement dans subdir
ou dans un sous-répertoire de subdir
, car %% capture à partir de la fin de la chaîne au lieu du début. Cela devrait être utile à tous ceux qui recherchent plus d'informations sur la substitution de paramètres: tldp.org/LDP/abs/html/parameter-substitution.html
Pour tester si une chaîne est le préfixe d'une autre, dans n'importe quel shell de style Bourne:
case $PWD/ in
/home/*) echo "home sweet home";;
*) echo "away from home";;
esac
Le même principe fonctionne pour un test de suffixe ou de sous-chaîne. Notez que dans les case
constructions, contrairement aux noms de fichiers, *
correspond à n'importe quel caractère, y compris un /
ou une initiale .
.
Dans les shells qui implémentent la [[ … ]]
syntaxe (ie bash, ksh et zsh), elle peut être utilisée pour faire correspondre une chaîne à un modèle. (Notez que la [
commande peut uniquement tester l'égalité des chaînes.)
if [[ $PWD/ = /home/* ]]; then …
Si vous testez spécifiquement si le répertoire actuel est en dessous /home
, un simple test de sous-chaîne ne suffit pas, à cause des liens symboliques.
S'il /home
s'agit d'un système de fichiers qui lui est propre, testez si le répertoire en cours ( .
) se trouve sur ce système de fichiers.
if [ "$(df -P . | awk 'NR==2 {print $6}')" = "/home" ]; then
echo 'The current directory is on the /home filesystem'
fi
Si vous avez NetBSD, OpenBSD ou GNU (c'est-à-dire Linux) readlink
, vous pouvez utiliser readlink -f
pour supprimer les liens symboliques d'un chemin.
case $(readlink -f .)/ in $(readlink -f /home)/*) …
Sinon, vous pouvez utiliser pwd
pour afficher le répertoire actuel. Mais vous devez faire attention à ne pas utiliser un shell intégré si votre shell suit les cd
commandes et conserve le nom que vous avez utilisé pour atteindre le répertoire plutôt que son emplacement «réel».
case $(pwd -P 2>/dev/null || env PWD= pwd)/ in
"$(cd /home && { pwd -P 2>/dev/null || env PWD= pwd; })"/*) …
Version brute:
[ ${PWD:0:6} = "/home/" ]
A l'inconvénient que l'on doit d'abord compter les caractères et qu'on ne peut pas les remplacer /home/
par quelque chose de général comme $1
.
modifier (merci @Michael) pour la généralisation à comparer avec $VAR
on peut utiliser
[ "${PWD:0:${#VAR}}" = $VAR ]
${#var}
est la longueur de $var
, vous pouvez donc la généraliser comme[ "${PWD:0:${#1}}" = "$1" ]
Je ne comprends pas trop bien la question, mais pour trouver le parent de $ PWD , faites-le dirname $PWD
. Pour trouver le parent du parent, exécutez dirname $(dirname $PWD)
, etc. ...
/
. D'accord, je pourrais vérifier récursivement, mais n'y a-t-il pas quelque chose de plus facile?
En utilisant awk
:
echo $PWD | awk -v h="/home" '$0 ~ h {print "MATCH"}'
Hm, c'est dommage de [
ne pas avoir la possibilité de tester la STRING1 starts with STRING2
condition.
Vous pouvez essayer echo $PWD | grep '^$VAR'
, mais il peut échouer de manière intéressante lorsqu'il VAR
contient des symboles spéciaux.
awk
La index
fonction devrait être capable de faire l'affaire. Mais tout cela semble trop lourd pour une chose aussi simple à tester.
Si la partie recherchée du chemin est trouvée, je "vide" la variable:
[[ -z "${PWD//*\/home\/*/}" ]] && echo "toto"
[ "${PWD##$VAR}" != "$PWD" ]
Et s'il s'agissait d'un [code-golf] ( stackoverflow.com/questions/tagged/code-golf)question vous m'auriez battu de deux caractères ;-) plus lisible ...