95 votes

Développer un chemin relatif possible dans bash

Comme arguments de mon script, il y a des chemins de fichiers. Celles-ci peuvent bien sûr être relatives (ou contenir ~). Mais pour les fonctions que j'ai écrites, j'ai besoin de chemins absolus, mais leurs liens symboliques ne sont pas résolus.

Y at-il une fonction pour cela?

85voto

Amir Afghani Points 17519

MY_PATH=$(readlink -f $YOUR_ARG) résoudra les chemins relatifs tels que "./" et "../"

Considérez ceci aussi ( source ):

 #!/bin/bash
dir_resolve()
{
cd "$1" 2>/dev/null || return $?  # cd to desired directory; if fail, quell any error messages but return exit status
echo "`pwd -P`" # output full, link-resolved path
}

# sample usage
if abs_path="`dir_resolve \"$1\"`"
then
echo "$1 resolves to $abs_path"
echo pwd: `pwd` # function forks subshell, so working directory outside function is not affected
else
echo "Could not reach $1"
fi
 

53voto

Mike Samuel Points 54712

http://www.linuxquestions.org/questions/programming-9/bash-script-return-full-path-and-filename-680368/page3.html présente les caractéristiques suivantes

 function abspath {
    if [[ -d "$1" ]]
    then
        pushd "$1" >/dev/null
        pwd
        popd >/dev/null
    elif [[ -e $1 ]]
    then
        pushd "$(dirname "$1")" >/dev/null
        echo "$(pwd)/$(basename "$1")"
        popd >/dev/null
    else
        echo "$1" does not exist! >&2
        return 127
    fi
}
 

qui utilise pushd - popd pour entrer dans un état où pwd est utile.

17voto

andsens Points 910

Simple one-liner:

 function abs_path {
  (cd "$(dirname '$1')" &>/dev/null && printf "%s/%s" "$(pwd)" "${1##*/}")
}
 

Usage:

 function do_something {
    local file=$(abs_path $1)
    printf "Absolute path to %s: %s\n" "$1" "$file"
}
do_something $HOME/path/to/some\ where
 

J'essaie toujours de comprendre comment je peux le faire complètement oublier que le chemin existe ou non (pour qu'il puisse également être utilisé lors de la création de fichiers).

2voto

Vitaly Kushner Points 3975

sur OS X, vous pouvez utiliser

 stat -f "%N" YOUR_PATH
 

sur linux, vous pourriez avoir realpath exécutable. sinon, ce qui suit pourrait fonctionner (pas seulement pour les liens):

 readlink -c YOUR_PATH
 

2voto

sja Points 175

Peut-être que ceci est plus lisible et n'utilise pas de sous-shell et ne change pas le répertoire actuel:

 dir_resolve() {
  local dir=`dirname "$1"`
  local file=`basename "$1"`
  pushd "$dir" &>/dev/null || return $? # On error, return error code
  echo "`pwd -P`/$file" # output full, link-resolved path with filename
  popd &> /dev/null
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X