Bash에서 가능한 상대 경로 확장
내 스크립트에 대한 인수로 일부 파일 경로가 있습니다. 물론 그것들은 상대적 일 수 있습니다 (또는 ~을 포함). 그러나 내가 작성한 함수의 경우 절대 경로가 필요하지만 심볼릭 링크가 해결되지 않았습니다.
이것에 대한 기능이 있습니까?
MY_PATH=$(readlink -f $YOUR_ARG)같은 상대 경로를 해결할 수 "./"및"../"
이것도 고려하십시오 ( 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
http://www.linuxquestions.org/questions/programming-9/bash-script-return-full-path-and-filename-680368/page3.html 에는 다음이 있습니다.
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
}
pushd/ popd를 사용 하여 pwd유용한 상태 가됩니다.
간단한 한 줄 :
function abs_path {
(cd "$(dirname '$1')" &>/dev/null && printf "%s/%s" "$PWD" "${1##*/}")
}
용법:
function do_something {
local file=$(abs_path $1)
printf "Absolute path to %s: %s\n" "$1" "$file"
}
do_something $HOME/path/to/some\ where
나는 여전히 경로가 존재하는지 여부를 완전히 알 수 없게 만드는 방법을 찾으려고 노력하고 있습니다 (따라서 파일을 만들 때도 사용할 수 있음).
이것은 OS X에서 나를 위해 트릭을 수행합니다. $(cd SOME_DIRECTORY 2> /dev/null && pwd -P)
어디에서나 작동합니다. 다른 솔루션은 너무 복잡해 보였습니다.
OS X에서 사용할 수 있습니다
stat -f "%N" YOUR_PATH
Linux에서는 realpath실행 파일 이있을 수 있습니다 . 그렇지 않은 경우 다음이 작동 할 수 있습니다 (링크뿐 아니라).
readlink -c YOUR_PATH
아마도 이것은 더 읽기 쉽고 서브 쉘을 사용하지 않으며 현재 디렉토리를 변경하지 않습니다.
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
}
자체 편집, 나는 OP가 해결 된 심볼릭 링크를 찾고 있지 않다고 말했습니다.
"하지만 내가 작성한 함수의 경우 절대 경로가 필요하지만 심볼릭 링크가 해결되지 않은 경로가 필요합니다."
그래서 이것은 결국 그의 질문에 그다지 적절하지 않다고 생각하십시오. :)
수년에 걸쳐이 문제를 여러 번 겪었고 이번에는 OSX와 Linux에서 사용할 수있는 순수한 bash 휴대용 버전이 필요했기 때문에 계속해서 다음을 작성했습니다.
살아있는 버전은 여기에 있습니다.
https://github.com/keen99/shell-functions/tree/master/resolve_path
하지만 그래서, 여기에 현재 버전이 있습니다 (잘 테스트되었다고 느낍니다 ..하지만 피드백에 열려 있습니다!)
평범한 bourne shell (sh)에서 작동하도록 만드는 것이 어렵지 않을 수도 있지만 시도하지 않았습니다. $ FUNCNAME을 너무 좋아합니다. :)
#!/bin/bash
resolve_path() {
#I'm bash only, please!
# usage: resolve_path <a file or directory>
# follows symlinks and relative paths, returns a full real path
#
local owd="$PWD"
#echo "$FUNCNAME for $1" >&2
local opath="$1"
local npath=""
local obase=$(basename "$opath")
local odir=$(dirname "$opath")
if [[ -L "$opath" ]]
then
#it's a link.
#file or directory, we want to cd into it's dir
cd $odir
#then extract where the link points.
npath=$(readlink "$obase")
#have to -L BEFORE we -f, because -f includes -L :(
if [[ -L $npath ]]
then
#the link points to another symlink, so go follow that.
resolve_path "$npath"
#and finish out early, we're done.
return $?
#done
elif [[ -f $npath ]]
#the link points to a file.
then
#get the dir for the new file
nbase=$(basename $npath)
npath=$(dirname $npath)
cd "$npath"
ndir=$(pwd -P)
retval=0
#done
elif [[ -d $npath ]]
then
#the link points to a directory.
cd "$npath"
ndir=$(pwd -P)
retval=0
#done
else
echo "$FUNCNAME: ERROR: unknown condition inside link!!" >&2
echo "opath [[ $opath ]]" >&2
echo "npath [[ $npath ]]" >&2
return 1
fi
else
if ! [[ -e "$opath" ]]
then
echo "$FUNCNAME: $opath: No such file or directory" >&2
return 1
#and break early
elif [[ -d "$opath" ]]
then
cd "$opath"
ndir=$(pwd -P)
retval=0
#done
elif [[ -f "$opath" ]]
then
cd $odir
ndir=$(pwd -P)
nbase=$(basename "$opath")
retval=0
#done
else
echo "$FUNCNAME: ERROR: unknown condition outside link!!" >&2
echo "opath [[ $opath ]]" >&2
return 1
fi
fi
#now assemble our output
echo -n "$ndir"
if [[ "x${nbase:=}" != "x" ]]
then
echo "/$nbase"
else
echo
fi
#now return to where we were
cd "$owd"
return $retval
}
다음은 brew 덕분에 고전적인 예입니다.
%% ls -l `which mvn`
lrwxr-xr-x 1 draistrick 502 29 Dec 17 10:50 /usr/local/bin/mvn@ -> ../Cellar/maven/3.2.3/bin/mvn
이 함수를 사용하면 -real- 경로를 반환합니다.
%% cat test.sh
#!/bin/bash
. resolve_path.inc
echo
echo "relative symlinked path:"
which mvn
echo
echo "and the real path:"
resolve_path `which mvn`
%% test.sh
relative symlinked path:
/usr/local/bin/mvn
and the real path:
/usr/local/Cellar/maven/3.2.3/libexec/bin/mvn
사용 readlink -f <relative-path>예 :
export FULLPATH=`readlink -f ./`
다른 방법이 있습니다. bash 스크립트에 python 임베딩을 사용하여 상대 경로를 확인할 수 있습니다.
abs_path=$(python3 - <<END
from pathlib import Path
path = str(Path("$1").expanduser().resolve())
print(path)
END
)
bash를 독점적으로 사용해야합니까? 이 작업을 수행해야했고 Linux와 OS X의 차이점에 싫증이났습니다. 그래서 빠르고 더러운 솔루션을 위해 PHP를 사용했습니다.
#!/usr/bin/php <-- or wherever
<?php
{
if($argc!=2)
exit();
$fname=$argv[1];
if(!file_exists($fname))
exit();
echo realpath($fname)."\n";
}
?>
나는 그것이 매우 우아한 해결책이 아니라는 것을 알고 있지만 작동합니다.
참고URL : https://stackoverflow.com/questions/7126580/expand-a-possible-relative-path-in-bash
'IT TIP' 카테고리의 다른 글
| PSCustomObject에서 Hashtable로 (0) | 2020.11.23 |
|---|---|
| 비트 시프트 (왼쪽 또는 오른쪽)의 기능과 용도는 무엇입니까? (0) | 2020.11.23 |
| setuptools에 정적 파일을 포함하는 방법-Python 패키지 (0) | 2020.11.23 |
| 보낸 사람의 이름이나 전자 메일 주소를 mutt에서 변경하는 방법은 무엇입니까? (0) | 2020.11.23 |
| 간단한 NGINX 로그 파일 분석기 (0) | 2020.11.23 |