Bash: получить абсолютный путь, заданный относительным - PullRequest
119 голосов
/ 14 ноября 2010

Есть ли команда для получения абсолютного пути по заданному пути?

Например, я хочу, чтобы $ line содержал абсолютный путь к каждому файлу в директории ./etc/

find ./ -type f | while read line; do
   echo $line
done

Ответы [ 18 ]

3 голосов
/ 14 ноября 2010

В случае find, вероятно, проще всего просто указать абсолютный путь для поиска, например ::1002*

find /etc
find `pwd`/subdir_of_current_dir/ -type f
2 голосов
/ 18 февраля 2019

Лучшее решение, imho, это то, которое выложено здесь: https://stackoverflow.com/a/3373298/9724628.

Для работы требуется python, но, похоже, он охватывает все или большинство крайних случаев и является очень переносимым решением.

  1. С разрешением символических ссылок:
python -c "import os,sys; print os.path.realpath(sys.argv[1])" path/to/file
  1. или без него:
python -c "import os,sys; print os.path.abspath(sys.argv[1])" path/to/file
1 голос
/ 25 августа 2016

Если вы хотите преобразовать переменную, содержащую относительный путь, в абсолютный, это работает:

   dir=`cd "$dir"`

«cd» эхосигналов без изменения рабочего каталога, поскольку выполняется здесь в под-оболочке.

1 голос
/ 14 марта 2016
echo "mydir/doc/ mydir/usoe ./mydir/usm" |  awk '{ split($0,array," "); for(i in array){ system("cd "array[i]" && echo $PWD") } }'
1 голос
/ 13 октября 2015

Если относительный путь является путем к каталогу, попробуйте мой, лучше всего:

absPath=$(pushd ../SOME_RELATIVE_PATH_TO_Directory > /dev/null && pwd && popd > /dev/null)

echo $absPath
1 голос
/ 14 ноября 2010

То, что они сказали, кроме find $PWD или (в bash) find ~+ немного удобнее.

1 голос
/ 13 мая 2015

Аналогично ответу @ ernest-a, но без влияния на $OLDPWD или определения новой функции, которую вы можете запустить подоболочкой (cd <path>; pwd)

$ pwd
/etc/apache2
$ cd ../cups 
$ cd -
/etc/apache2
$ (cd ~/..; pwd)
/Users
$ cd -
/etc/cups
0 голосов
/ 05 июля 2019

Это связанное решение от всех остальных, например, когда realpath дает сбой, либо из-за того, что он не установлен, либо из-за выхода с кодом ошибки, затем предпринимается попытка следующего решения, пока он не получит правильный путь.

#!/bin/bash

function getabsolutepath() {
    local target;
    local changedir;
    local basedir;
    local firstattempt;

    target="${1}";
    if [ "$target" == "." ];
    then
        printf "%s" "$(pwd)";

    elif [ "$target" == ".." ];
    then
        printf "%s" "$(dirname "$(pwd)")";

    else
        changedir="$(dirname "${target}")" && basedir="$(basename "${target}")" && firstattempt="$(cd "${changedir}" && pwd)" && printf "%s/%s" "${firstattempt}" "${basedir}" && return 0;
        firstattempt="$(readlink -f "${target}")" && printf "%s" "${firstattempt}" && return 0;
        firstattempt="$(realpath "${target}")" && printf "%s" "${firstattempt}" && return 0;

        # If everything fails... TRHOW PYTHON ON IT!!!
        local fullpath;
        local pythoninterpreter;
        local pythonexecutables;
        local pythonlocations;

        pythoninterpreter="python";
        declare -a pythonlocations=("/usr/bin" "/bin");
        declare -a pythonexecutables=("python" "python2" "python3");

        for path in "${pythonlocations[@]}";
        do
            for executable in "${pythonexecutables[@]}";
            do
                fullpath="${path}/${executable}";

                if [[ -f "${fullpath}" ]];
                then
                    # printf "Found ${fullpath}\\n";
                    pythoninterpreter="${fullpath}";
                    break;
                fi;
            done;

            if [[ "${pythoninterpreter}" != "python" ]];
            then
                # printf "Breaking... ${pythoninterpreter}\\n"
                break;
            fi;
        done;

        firstattempt="$(${pythoninterpreter} -c "import os, sys; print( os.path.abspath( sys.argv[1] ) );" "${target}")" && printf "%s" "${firstattempt}" && return 0;
        # printf "Error: Could not determine the absolute path!\\n";
        return 1;
    fi
}

printf "\\nResults:\\n%s\\nExit: %s\\n" "$(getabsolutepath "./asdfasdf/ asdfasdf")" "${?}"
...