Question: existe-t-il une simple commande sh / bash / zsh / fish / ... pour imprimer le chemin absolu du fichier que je l'alimente?
Utilisation cas: Je suis dans le répertoire /a/b
et je voudrais imprimer le chemin complet vers le fichier c
sur la ligne de commande afin que je puisse facilement le coller dans un autre programme: /a/b/c
. Simple, mais un petit programme pour le faire pourrait probablement me faire gagner environ 5 secondes lorsqu'il s'agit de gérer de longs chemins, ce qui en fin de compte s'additionne. Cela me surprend donc que je ne trouve pas d'utilitaire standard pour le faire - n'y en a-t-il vraiment pas?
Voici un exemple d'implémentation, abspath.py:
#!/usr/bin/python
# Author: Diggory Hardy <[email protected]>
# Licence: public domain
# Purpose: print the absolute path of all input paths
import sys
import os.path
if len(sys.argv)>1:
for i in range(1,len(sys.argv)):
print os.path.abspath( sys.argv[i] )
sys.exit(0)
else:
print >> sys.stderr, "Usage: ",sys.argv[0]," PATH."
sys.exit(1)
Réponses:
Essayez
realpath
.la source
realpath
composé de: github.com/westonruter/misc-cli-tools/blob/master/realpathEssayez
readlink
qui résoudra les liens symboliques:la source
-m
c'est la meilleure option à utiliser./usr/bin/readlink
sur Mavericks. Ou vouliez-vous dire que ces options ne se trouvent pas sur OS X? Il semble que ce soit une version BSD rabougrie ...: preadlink
page deonly the target of the symbolic link is printed. If the given argument is not a symbolic link, readlink will print nothing and exit with an error
manuel BSD :, donc readlink ne fonctionnera pas à cet effet sur OSXla source
a b
(deux espaces entre a et b, SO en mange un).function realpath { echo $(cd $(dirname $1); pwd)/$(basename $1); }
de me faire unerealpath
commande (réponse actuellement acceptée) sur OS X. Merci!LOG=$(echo $(cd $(dirname $0); pwd)/$(basename $0 .sh).log)
Oublier
readlink
etrealpath
qui peut ou ne peut pas être installé sur votre système.Développant la réponse de Dogbane ci-dessus, elle est exprimée en fonction:
vous pouvez ensuite l'utiliser comme ceci:
Comment et pourquoi ça marche?
La solution exploite le fait que la
pwd
commande intégrée Bash affichera le chemin absolu du répertoire courant lorsqu'elle sera invoquée sans arguments.Pourquoi j'aime cette solution?
Il est portable et ne nécessite pas non plus
readlink
ourealpath
qui n'existe souvent pas sur une installation par défaut d'un distro Linux / Unix donné.Et si dir n'existe pas?
Comme indiqué ci-dessus, la fonction échouera et s'imprimera sur stderr si le chemin de répertoire donné n'existe pas. Ce n'est peut-être pas ce que vous voulez. Vous pouvez développer la fonction pour gérer cette situation:
Maintenant, il retournera une chaîne vide si l'un des répertoires parents n'existe pas.
Comment gérez-vous les «..» ou les «.» en entrée?
Eh bien, cela donne un chemin absolu dans ce cas, mais pas minimal. Cela ressemblera à:
Si vous voulez résoudre le «..», vous devrez faire le script comme:
la source
realpath
vient du paquet coreutils, qui contient également des outils tels quewho
,touch
oucat
. Il s'agit d'un ensemble d'outils GNU assez standard, vous pouvez donc être sûr qu'il est installé sur presque toutes les machines basées sur Linux.Cela dit, vous avez raison: il y a 2 problèmes avec: i) vous le manquerez probablement dans l'installation par défaut sur systèmes non GNU unix (comme OpenBSD) ii) ces outils ont été introduits dans la version 8.15 (donc c'est assez nouveau, à partir de 2012), donc vous le manquerez sur les systèmes stables à long terme (comme RHEL 6).C'est mieux que
readlink -e FILE
ourealpath
, car cela fonctionne même si le fichier n'existe pas.la source
-m
option n'est pas disponible sur Mavericks.Ce chemin relatif vers la fonction shell du convertisseur de chemin absolu
cd
etpwd
)..
et.
Code:
Échantillon:
Remarque: Ceci est basé sur les réponses de nolan6000 et bsingh , mais corrige le cas du fichier.
Je comprends également que la question d'origine concernait un utilitaire de ligne de commande existant. Mais comme cela semble être LA question sur stackoverflow pour cela, y compris les scripts shell qui veulent avoir des dépendances minimales, j'ai mis cette solution de script ici, donc je peux la trouver plus tard :)
la source
$ abspath 'a b c/file.txt'
-à-dire parce que l'argument tocd
n'est pas cité. Pour surmonter cela, au lieu de citer l'intégralité de l'argumentecho
(y a-t-il une raison à ces citations?), Ne citer que les arguments du chemin. Ie remplacerecho "$(cd ${1%/*}; pwd)/${1##*/}"
parecho $(cd "${1%/*}"; pwd)/${1##*/}
.echo "$(cd "$1"; pwd)"
par(cd "$1"; pwd)
. Il n'y a pas besoin d'écho ici.( ... )
sont toujours nécessaires, donccd
cela se passe dans un sous-shell, car nous ne voulons pas changer le répertoire de travail pour les appelants deabspath
.La
find
commande peut aiderRépertorie tous les fichiers dans ou sous le répertoire actuel avec des noms correspondant au modèle. Vous pouvez le simplifier si vous n'obtiendrez que quelques résultats (par exemple un répertoire au bas de l'arborescence contenant peu de fichiers), juste
Je l'utilise sur Solaris 10, qui n'a pas les autres utilitaires mentionnés.
la source
PWD
, vous pouvez simplement utiliser$PWD/$filename
.Si vous n'avez pas d'utilitaires readlink ou realpath, vous pouvez utiliser la fonction suivante qui fonctionne en bash et zsh (pas sûr du reste).
Cela fonctionne également pour les fichiers inexistants (tout comme la fonction python
os.path.abspath
).Malheureusement,
abspath ./../somefile
ne se débarrasse pas des points.la source
echo "$1"
parprintf "%s\n" "$1"
(idem avec le deuxième écho).echo
peut interpréter des barres obliques inverses à l'intérieur de ses arguments.Voici une fonction uniquement zsh que j'aime pour sa compacité. Il utilise le modificateur d'expansion 'A' - voir zshexpn (1).
la source
Il n'y a généralement pas une telle chose que l'
absolute path
un fichier (ce moyen de déclaration qu'il peut y avoir plus d'un général, d' où l'utilisation de l'article défini l' est pas approprié). Anabsolute path
est un chemin qui part de la racine "/" et désigne un fichier sans ambiguïté indépendamment du répertoire de travail (voir par exemple wikipedia ).A
relative path
est un chemin qui doit être interprété à partir d'un autre répertoire. Il peut s'agir du répertoire de travail s'il s'agit d'unrelative path
être manipulé par une application (mais pas nécessairement). Lorsqu'il se trouve dans un lien symbolique dans un répertoire, il est généralement destiné à être relatif à ce répertoire (bien que l'utilisateur puisse avoir d'autres utilisations en tête).Par conséquent, un chemin absolu n'est qu'un chemin relatif au répertoire racine.
Un chemin (absolu ou relatif) peut contenir ou non des liens symboliques. Si ce n'est pas le cas, il est également quelque peu imperméable aux changements dans la structure de liaison, mais ce n'est pas nécessairement requis ni même souhaitable. Certaines personnes appellent
canonical path
(oucanonical file name
ouresolved path
) unabsolute path
dans lequel tous les liens symboliques ont été résolus, c'est-à-dire qu'ils ont été remplacés par un chemin vers tout ce vers quoi ils se connectent. Les commandesrealpath
et lesreadlink
deux recherchent un chemin canonique, mais n'ontrealpath
qu'une option pour obtenir un chemin absolu sans se soucier de résoudre les liens symboliques (ainsi que plusieurs autres options pour obtenir différents types de chemins, absolus ou relatifs à certains répertoires).Cela appelle plusieurs remarques:
realpath
etreadlink
ont des options pour en tenir compte.canonical
. Par conséquent, le concept dépend du temps (ou de l'environnement).canonical path
vers un fichier, pour deux raisons:ro
) sur plusieurs points de montage.Par conséquent, même avec la définition beaucoup plus restrictive de
canonical path
, il peut y avoir plusieurs chemins canoniques vers un fichier. Cela signifie également que le qualificatifcanonical
est quelque peu inadéquat car il implique généralement une notion d'unicité.Cela développe une brève discussion du sujet dans une réponse à une autre question similaire à Bash: récupérer le chemin absolu étant donné relatif
Ma conclusion est que
realpath
c'est mieux conçu et beaucoup plus flexible quereadlink
. La seule utilisation dereadlink
cela n'est pas couverte parrealpath
l'appel sans option renvoyant la valeur d'un lien symbolique.la source
realpath
vsreadlink
ou même sur les liens symboliques sont excédentaires à ce que j'ai demandé.canonical
fait précisément référence à cette unicité par rapport à un ensemble de transformations. Mais, par exemple, / dev / cdrom est un chemin absolu parfaitement bon, même s'il s'agit en fait d'un lien vers / dev / sr0. Les deux pointent vers le même appareil. Ma réponse originale indiquait un article Web pertinent.La
dogbane
réponse avec la description de ce qui se passe:Explication:
"$1"
dirname "$1"
cd "$(dirname "$1")
dans ce répertoire relatif et obtenons le chemin absolu pour celui-ci en exécutant lapwd
commande shell$(basename "$1")
echo
nela source
Pour les répertoires
dirname
est déclenché../
et retourne./
.La fonction de nolan6000 peut être modifiée pour corriger cela:
la source
.profile
et donc disponible pour une utilisation interactive.$1
c'est un nom de fichier simple:get_abs_filename foo
-> rien (ou<current_dir>/foo/foo
sifoo
c'est un répertoire).Ce n'est pas une réponse à la question, mais pour ceux qui font du script:
il gère / .. ./ etc correctement. Je semble aussi travailler sur OSX
la source
J'ai placé le script suivant sur mon système et je l'appelle comme un alias bash lorsque je veux saisir rapidement le chemin d'accès complet à un fichier dans le répertoire actuel:
Je ne sais pas pourquoi, mais sous OS X quand il est appelé par un script "$ PWD" se développe sur le chemin absolu. Lorsque la commande find est appelée sur la ligne de commande, elle ne le fait pas. Mais il fait ce que je veux ... profiter.
la source
$PWD
a toujours le chemin absolu du répertoire de travail. De plus,find
ne tolérera pas les barres obliques, vous ne répondez donc pas à la question comme demandé. Une façon plus rapide de faire ce que vous cherchez à faire serait tout simplementecho "$PWD/$1"
Le plus simple si vous souhaitez utiliser uniquement des builtins est probablement:
Seulement deux mots supplémentaires à taper, et cela fonctionnera sur tous les systèmes Unix, ainsi que OSX.
la source
-maxdepth 1
avant-name
(en supposant que le fichier se trouve dans le répertoire courant). Sans cela, il fonctionnera avec des fichiers dans n'importe quel sous-répertoire de pwd, mais pas avec d'autres.find
pas trouver un fichier en dehors de l'arborescence de répertoires en dessouspwd
. Par exemple, si vous essayezfind . -name ../existingFile
, cela échoue.Cela compense les lacunes de
realpath
, stockez-le dans un script shellfullpath
. Vous pouvez maintenant appeler:la source
realpath "foo bar"
->/home/myname/foo bar
. Si vous ne pouvez pas prendre la peine de citer des arguments de ligne de commande, ce n'est pasrealpath
la faute.Une alternative pour obtenir le chemin absolu en Ruby :
realpath() {ruby -e "require 'Pathname'; puts Pathname.new('$1').realpath.to_s";}
Fonctionne sans arguments (dossier actuel) et chemin de fichier ou de dossier relatif et absolu comme agument.
la source
Répondre avec Homebrew
realpath
est la meilleure réponse, mais si vous ne l'avez pas installé, vous devez d'abord exécuterbrew install coreutils
ce qui installera coreutils avec beaucoup de fonctions impressionnantes. Écrire une fonction personnalisée et l'exporter est trop de travail et risque d'erreur pour quelque chose comme ça, voici deux lignes:la source
Hé les gars, je sais que c'est un vieux fil de discussion, mais je poste juste ceci pour référence à toute autre personne qui a visité ce site comme moi. Si j'ai bien compris la question, je pense que la
locate $filename
commande. Il affiche le chemin absolu du fichier fourni, mais uniquement s'il existe.la source
locate
est un utilitaire pour rechercher des fichiers / chemins par leur nom. Il peut faire le travail mais peut également trouver d'autres correspondances et ne pas trouver un fichier existant sans appeler enupdatedb
tant que root en premier.