현재 작업 디렉토리가 아닌 파일 위치에 기반한 상대 경로
지정:
some.txt
dir
|-cat.sh
고양이랑.sh 내용:
cat ../some.txt
후 실행 중"을 실행합니다../cat.sh에 inside inside inside dir합니다../dir/cat.sh로 같은 dir 디렉토리가 것 요.작업 디렉토리가 다르기 때문일 것으로 예상됩니다.를 쉽게 수 있는 방법이 요?../some.txt에 cat.sh
입니다(사용할 수 것은 스크립트의 절대경로입니다).${BASH_SOURCE[0]}으로 이를 하여 부모 와 ""를 cd★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
#!/bin/bash
parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
cd "$parent_path"
cat ../some.text
이것에 의해, 셸 스크립트는 어디에서 기동하는지에 관계없이 동작합니다. '달리다'를 하는 것 이 듭니다./cat.sh에 inside inside inside dir.
이 스크립트는 스크립트를 직접 호출하는 경우(즉, 심볼링크가 아닌 경우)에만 작동합니다.그렇지 않으면 스크립트의 현재 위치를 찾는 것이 조금 더 어려워집니다.
@Martin Konecny의 답변은 효과적인 솔루션을 제공하지만, 그가 언급했듯이 실제 스크립트가 다른 디렉토리에 있는 심볼링크를 통해 호출되지 않는 경우에만 작동합니다.
이 답변에서는 이러한 경우를 다룹니다.이 솔루션은 심볼링크 또는 심볼링크 체인을 통해 스크립트를 호출할 때도 작동합니다.
Linux/GNU 솔루션:
스크립트가 Linux에서만 실행되어야 하는 경우 또는 GNU가 에 있는 것을 알고 있는 경우$PATH하다, 사용하다readlink -f최종 타깃에 대한 심볼링크를 쉽게 해결합니다.
scriptDir=$(dirname -- "$(readlink -f -- "$BASH_SOURCE")")
GNU GNU †에해 주세요.readlink풀패스에 .즉, 3가지 옵션이 있습니다.-f )--canonicalize-e )--canonicalize-existing및 , 。-m )--canonicalize-missing - 를 해 주세요.man readlink.
중 수 이 시나리오에서는 3가지 옵션을 -f가장 잘 알려진 곳이기 때문입니다.
멀티(Unix와 같은) 플랫폼 솔루션(POSIX만의 유틸리티 세트를 갖춘 플랫폼 포함):
스크립트가 다음 플랫폼에서 실행되어야 하는 경우:
가지고 있다
readlink「」가 .-f옵션(GNU의 의미에서는 최종 타깃에 대한 심볼링크를 해결합니다) - 예를 들어 macOS.- macOS는 이전 버전의 BSD 구현을 사용합니다.
readlink; FreeBSD/PC-BSD의 최신 버전은-f.
- macOS는 이전 버전의 BSD 구현을 사용합니다.
가지고 있지 않다
readlink단, HP-UX(@Charles Duffy)와 같은 POSIX 호환 유틸리티가 있습니다.
https://stackoverflow.com/a/1116890/45375,에 영감을 받은 다음 솔루션은 도우미 셸 기능을 정의하며, 이 기능은 POSIX-Link(NUIXX 호환 구현에 영향을 미치는 영향입니다.궁극적인 대상이 있어야 합니다.
주의: 이 기능은 기능이며 POSIX 호환 옵션을 가진 POSIX 유틸리티만 사용한다는 점에서 POSIX 호환입니다.POSIX 준거 셸 코드로 기술되어 있는 이 함수의 버전(용)/bin/sh를 참조해 주세요.
한다면
readlink사용할 수 있습니다. (옵션 없이) 사용됩니다.대부분의 최신 플랫폼에 해당됩니다.그 이외의 경우는, 로부터의 출력이 됩니다.
ls -l는 해석됩니다.이것은 심볼링크 타깃을 판별하는 유일한 POSIX 준거 방법입니다.
경고: 파일 이름 또는 경로에 리터럴 하위 문자열이 포함되어 있으면 중단됩니다.->- 하지만 그럴 가능성은 낮습니다.
(플랫폼에 주의해 주세요.readlink@Charles Duffy는 HP-UX의 심볼링크를 해결하기 위한 다른 비 POSIX 방법을 제공할 수 있습니다.find를 지원하는 유틸리티%lchar.를 포맷합니다.-printf주요, 간결성을 위해 함수는 이러한 경우를 감지하려고 하지 않습니다.)설치 가능한 유틸리티(스크립트) 형식의 함수는 npm 레지스트리에서 찾을
rreadlink수 있습니다.Linux 및 macOS 에서는, 인스톨 합니다.[sudo] npm install -g rreadlink있다; 있다;;;;;;bash)의 인스톨 순서에 따릅니다.
인수가 심볼 링크인 경우 최종 대상의 표준 경로가 반환되고, 그렇지 않은 경우 인수의 자체 표준 경로가 반환됩니다.
#!/usr/bin/env bash
# Helper function.
rreadlink() ( # execute function in a *subshell* to localize the effect of `cd`, ...
local target=$1 fname targetDir readlinkexe=$(command -v readlink) CDPATH=
# Since we'll be using `command` below for a predictable execution
# environment, we make sure that it has its original meaning.
{ \unalias command; \unset -f command; } &>/dev/null
while :; do # Resolve potential symlinks until the ultimate target is found.
[[ -L $target || -e $target ]] || { command printf '%s\n' "$FUNCNAME: ERROR: '$target' does not exist." >&2; return 1; }
command cd "$(command dirname -- "$target")" # Change to target dir; necessary for correct resolution of target path.
fname=$(command basename -- "$target") # Extract filename.
[[ $fname == '/' ]] && fname='' # !! curiously, `basename /` returns '/'
if [[ -L $fname ]]; then
# Extract [next] target path, which is defined
# relative to the symlink's own directory.
if [[ -n $readlinkexe ]]; then # Use `readlink`.
target=$("$readlinkexe" -- "$fname")
else # `readlink` utility not available.
# Parse `ls -l` output, which, unfortunately, is the only POSIX-compliant
# way to determine a symlink's target. Hypothetically, this can break with
# filenames containig literal ' -> ' and embedded newlines.
target=$(command ls -l -- "$fname")
target=${target#* -> }
fi
continue # Resolve [next] symlink target.
fi
break # Ultimate target reached.
done
targetDir=$(command pwd -P) # Get canonical dir. path
# Output the ultimate target's canonical path.
# Note that we manually resolve paths ending in /. and /.. to make sure we
# have a normalized path.
if [[ $fname == '.' ]]; then
command printf '%s\n' "${targetDir%/}"
elif [[ $fname == '..' ]]; then
# Caveat: something like /var/.. will resolve to /private (assuming
# /var@ -> /private/var), i.e. the '..' is applied AFTER canonicalization.
command printf '%s\n' "$(command dirname -- "${targetDir}")"
else
command printf '%s\n' "${targetDir%/}/$fname"
fi
)
# Determine ultimate script dir. using the helper function.
# Note that the helper function returns a canonical path.
scriptDir=$(dirname -- "$(rreadlink "$BASH_SOURCE")")
한 줄이면 돼요.
cat "`dirname $0`"/../some.txt
언급URL : https://stackoverflow.com/questions/24112727/relative-paths-based-on-file-location-instead-of-current-working-directory
'programing' 카테고리의 다른 글
| 이클립스 코드 라인 수 (0) | 2023.04.27 |
|---|---|
| 데이터를 덮어쓰지 않고 기존 Excel 파일에 쓰는 방법(팬더 사용) (0) | 2023.04.27 |
| Swift 옵션 값은 무엇입니까? (0) | 2023.04.22 |
| Excel 또는 스프레드시트 열 문자를 피토닉 방식으로 숫자로 변환 (0) | 2023.04.22 |
| UIScrollView를 프로그래밍 방식으로 맨 아래로 스크롤합니다. (0) | 2023.04.22 |