les citations à l'intérieur sont importantes ou vous perdrez toutes vos données
catamphétamine
11
et la variante que j'utilise pour obtenir le parent du répertoire de travail actuel: parentdir=$(dirname `pwd`)
TheGrimmScientist
3
Notez que cette méthode n'est pas sécurisée pour les noms "moches". Un nom comme "-rm -rf" rompra le comportement souhaité. Probablement "." le fera aussi. Je ne sais pas si c'est la meilleure façon, mais j'ai créé une question distincte "axée sur l'exactitude" ici: stackoverflow.com/questions/40700119/…
VasiliNovikov
4
@Christopher Shroba Oui, j'ai omis les guillemets, puis mon disque dur s'est retrouvé partiellement essuyé. Je ne me souviens pas exactement de ce qui s'est passé: vraisemblablement un répertoire blanc non guidé l'a fait effacer le répertoire parent au lieu du répertoire cible - mon script vient d'effacer le dossier / home / xxx /.
catamphétamine
3
oh d'accord, il n'y a donc rien sur la commande qui entraînerait la perte de données, sauf si vous émettez déjà une commande de suppression, non? C'était juste une question de chemin que vous essayiez de supprimer, de vous séparer d'un personnage d'espace et de supprimer beaucoup plus que prévu?
Christopher Shroba
18
... mais ce qui est "vu ici " est cassé. Voici le correctif:
Utilisez-le echo $(cd ../ && pwd)tout en travaillant dans le répertoire dont vous souhaitez découvrir le répertoire parent. Cette chaîne présente également l'avantage supplémentaire de ne pas avoir de barres obliques de fin.
L'utilisation evaln'est PAS géniale s'il y a une chance d'analyser les entrées des utilisateurs qui pourraient vous mettre dans un endroit inattendu ou exécuter de mauvaises choses contre votre système. Pouvez-vous utiliser à la pushd $dir 2>&1 >/dev/null && pwd && popd 2>&1 >/dev/nullplace du eval?
dragon788
2
Vous n'avez pas besoin evaldu tout: faites-le parentdir=$(cd -- "$dir" && pwd). Puisque le cdest exécuté en sous-shell, vous n'avez pas besoin de cdrevenir là où nous étions. Le --est ici au cas où l'expansion de $dircommence par un trait d'union. Le but &&est simplement d'empêcher parentdird'avoir un contenu non vide lorsque le cdn'a pas réussi.
gniourf_gniourf
8
Motivation pour une autre réponse
J'aime le code très court, clair et garanti. Point bonus s'il n'exécute pas de programme externe, car le jour où vous aurez besoin de traiter un grand nombre d'entrées, il sera sensiblement plus rapide.
Principe
Je ne sais pas quelles garanties vous avez et voulez, donc offrez quand même.
Si vous avez des garanties, vous pouvez le faire avec un code très court. L'idée est d'utiliser la fonction de substitution de texte bash pour couper la dernière barre oblique et tout ce qui suit.
Réponse de cas simples à plus complexes de la question d'origine.
Si le chemin est garanti de se terminer sans aucune barre oblique (entrée et sortie)
Si le chemin d'entrée peut se terminer par zéro ou une barre oblique (pas plus) et que vous souhaitez que le chemin de sortie se termine sans barre oblique
for P in \
/home/smith/Desktop/Test \
/home/smith/Desktop/Test/do
P_ENDNOSLASH="${P%/}"; echo "${P_ENDNOSLASH%/*}"done/home/smith/Desktop/home/smith/Desktop
Si le chemin d'entrée peut avoir de nombreuses barres obliques et que vous souhaitez que le chemin de sortie se termine sans barre oblique
for P in \
/home/smith/Desktop/Test \
/home/smith/Desktop/Test/ \
/home/smith///Desktop////Test//do
P_NODUPSLASH="${P//\/*(\/)/\/}"
P_ENDNOSLASH="${P_NODUPSLASH%%/}"
echo "${P_ENDNOSLASH%/*}";done/home/smith/Desktop/home/smith/Desktop/home/smith/Desktop
Réponse fantastique. Comme il semble qu'il cherchait un moyen de le faire à partir d'un script (trouver le répertoire actuel du script et son parent et faire quelque chose par rapport à l'emplacement du script), c'est une excellente réponse et vous pouvez encore plus contrôler si l'entrée a une barre oblique de fin ou non en utilisant l'expansion des paramètres par rapport à ${BASH_SOURCE[0]}laquelle serait le chemin d'accès complet au script s'il n'était pas fourni via sourceou ..
dragon788
7
Si /home/smith/Desktop/Test/../c'est ce que vous voulez:
désolé, je veux dire dans comme un script bash, j'ai une variable avec le chemin du fichier
YTKColumba
L'exécution de ce code me donne l'erreur bash: dirname 'Test': syntax error: invalid arithmetic operator (error token is "'Test'"). Le code lié est également incorrect.
Michael Hoffman
essayez de simplement lancer à dirname Testpartir du répertoire Test.
Jon Egeland
1
Selon que vous avez besoin de chemins absolus, vous voudrez peut-être faire un pas supplémentaire:
local lookFor_ parent_ switch_ i_
lookFor_="$1"#if it is not a file, we need the grand parent[-f "$lookFor_"]|| switch_="/.."#length of search string
i_="${#lookFor_}"#remove string one by one until it make sens for the systemwhile["$i_"-ge 0]&&[!-d "${lookFor_:0:$i_}"];do
let i_--done#get real path
parent_="$(realpath "${lookFor_:0:$i_}$switch_")"#done
echo "
lookFor_: $1
{lookFor_:0:$i_}: ${lookFor_:0:$i_}
realpath {lookFor_:0:$i_}: $(realpath ${lookFor_:0:$i_})
parent_: $parent_
"
si , pour quelque raison que ce qui vous intéresse pour naviguer dans un certain nombre spécifique de répertoires que vous pouvez également faire: nth_path=$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd ../../../ && pwd). Cela donnerait 3 répertoires aux parents
..
', mais ce n'est peut-être pas tout à fait ce que vous aviez en tête.Réponses:
Fonctionne également s'il y a une barre oblique.
la source
parentdir=$(dirname `pwd`)
... mais ce qui est "vu ici " est cassé. Voici le correctif:
la source
Utilisez-le
echo $(cd ../ && pwd)
tout en travaillant dans le répertoire dont vous souhaitez découvrir le répertoire parent. Cette chaîne présente également l'avantage supplémentaire de ne pas avoir de barres obliques de fin.la source
echo
ici.De toute évidence, le répertoire parent est donné en ajoutant simplement le nom de fichier point à point:
Mais vous devez vouloir le chemin résolu (un chemin absolu sans aucun composant de chemin point à point):
Le problème avec les meilleures réponses qui utilisent
dirname
, c'est qu'elles ne fonctionnent pas lorsque vous entrez un chemin avec des points:C'est plus puissant :
Vous pouvez le nourrir
/home/smith/Desktop/Test/..
, mais aussi des chemins plus complexes comme:EDIT: Si cela ne fonctionne pas, vérifiez que votre
cd
n'a pas été modifié, comme c'est parfois le cas,la source
eval
n'est PAS géniale s'il y a une chance d'analyser les entrées des utilisateurs qui pourraient vous mettre dans un endroit inattendu ou exécuter de mauvaises choses contre votre système. Pouvez-vous utiliser à lapushd $dir 2>&1 >/dev/null && pwd && popd 2>&1 >/dev/null
place dueval
?eval
du tout: faites-leparentdir=$(cd -- "$dir" && pwd)
. Puisque lecd
est exécuté en sous-shell, vous n'avez pas besoin decd
revenir là où nous étions. Le--
est ici au cas où l'expansion de$dir
commence par un trait d'union. Le but&&
est simplement d'empêcherparentdir
d'avoir un contenu non vide lorsque lecd
n'a pas réussi.Motivation pour une autre réponse
J'aime le code très court, clair et garanti. Point bonus s'il n'exécute pas de programme externe, car le jour où vous aurez besoin de traiter un grand nombre d'entrées, il sera sensiblement plus rapide.
Principe
Je ne sais pas quelles garanties vous avez et voulez, donc offrez quand même.
Si vous avez des garanties, vous pouvez le faire avec un code très court. L'idée est d'utiliser la fonction de substitution de texte bash pour couper la dernière barre oblique et tout ce qui suit.
Réponse de cas simples à plus complexes de la question d'origine.
Si le chemin est garanti de se terminer sans aucune barre oblique (entrée et sortie)
Si le chemin est garanti de se terminer avec exactement une barre oblique (entrée et sortie)
Si le chemin d'entrée peut se terminer par zéro ou une barre oblique (pas plus) et que vous souhaitez que le chemin de sortie se termine sans barre oblique
Si le chemin d'entrée peut avoir de nombreuses barres obliques et que vous souhaitez que le chemin de sortie se termine sans barre oblique
la source
${BASH_SOURCE[0]}
laquelle serait le chemin d'accès complet au script s'il n'était pas fourni viasource
ou.
.Si
/home/smith/Desktop/Test/../
c'est ce que vous voulez:comme on le voit ici .
la source
bash: dirname 'Test': syntax error: invalid arithmetic operator (error token is "'Test'")
. Le code lié est également incorrect.dirname Test
partir du répertoireTest
.Selon que vous avez besoin de chemins absolus, vous voudrez peut-être faire un pas supplémentaire:
la source
utilisez ceci:
export MYVAR="$(dirname "$(dirname "$(dirname "$(dirname $PWD)")")")"
si vous voulez le 4ème répertoire parentexport MYVAR="$(dirname "$(dirname "$(dirname $PWD)")")"
si vous voulez le 3ème répertoire parentexport MYVAR="$(dirname "$(dirname $PWD)")"
si vous voulez le 2ème répertoire parentla source
moche mais efficace
{
}
la source
Partant de l'idée / du commentaire Charles Duffy - 17 décembre 14 à 17h32 sur le sujet Obtenir le nom du répertoire actuel (sans chemin complet) dans un script Bash
la source
si , pour quelque raison que ce qui vous intéresse pour naviguer dans un certain nombre spécifique de répertoires que vous pouvez également faire:
nth_path=$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd ../../../ && pwd)
. Cela donnerait 3 répertoires aux parentsla source