$ PATH에있는 동일한 스크립트 디렉토리에있는 파일을 참조하십시오.


33

bash 스크립트 파일이 있습니다.이 디렉토리는 $ PATH에 추가 된 디렉토리에 배치되어 모든 디렉토리에서 스크립트를 호출 할 수 있습니다.

스크립트와 동일한 디렉토리에 다른 텍스트 파일이 있습니다. 스크립트에서 텍스트 파일을 참조하는 방법이 궁금합니다.

예를 들어, 스크립트가 텍스트 파일의 내용을 출력하는 것이라면 cat textfile다른 디렉토리에서 스크립트를 호출 할 때 텍스트 파일을 찾을 수 없으므로 작동하지 않습니다.


관련 문제가 최근에 여기에 나타났습니다 : symlink를 통해 실행될 때 현재 스크립트의 경로를 얻으십시오
Caleb

안정적으로 bash는 스크립트 파일의 경로를 얻을 수있는 방법이 질문에 대답, 나는 내 길에 그 추가 : stackoverflow.com/q/4774054/1695680
ThorSummoner

답변:


24

(경로 확장 또는 스크립트 자체에) 심볼릭 링크가 없으면 다음과 같이 작동합니다.

  • MYDIR="$(dirname "$(realpath "$0")")"

  • MYDIR="$(dirname "$(which "$0")")"

  • 위의 두 단계 버전 :

    MYSELF="$(realpath "$0")"

    MYDIR="${MYSELF%/*}"

스크립트로가는 도중에 심볼릭 링크가 있으면 which해당 링크의 해결을 포함하지 않는 답변을 제공합니다. realpath시스템에 기본적으로 설치되어 있지 않은 경우 여기에서 찾을 수 있습니다 .

[편집] : Caleb가 제안한 것보다 realpath이점이없는 것 readlink -f 같으 므로 후자를 사용하는 것이 좋습니다. 내 타이밍 테스트는 실제로 더 빠르다는 것을 나타냅니다.


문제 없어. 그건 그렇고 realpath시스템에서 어디로 오는가. (이없는 다른 사람들을 위해 사용할 수 있습니다readlink -f
Caleb

@Caleb 사실 나는 그것이 표준 GNU 유틸리티 (coreutils)에 속해 있다고 생각했지만 지금은 별도의 패키지 라는 것을 알 수 있습니다 .
rozcietrzewiacz

@rozcietrzewiacz 는 GNU coreutils (이전에는 IIRC)가 사용 realpath되기 전 readlink -f( 이전 에도 readlink비슷한 도구가 여러 개있었습니다. readlink -f결국 사실상 표준이되었습니다). realpath여전히 사용하는 스크립트와의 호환성을 위해서만 유지됩니다.
Gilles 'SO- 악마 그만

세드릭의 장점 $(dirname "$(which "$0")")을 통해 $(dirname $0)(가) 어디에 which더 이상 존재? 동일하지 않습니까?
UlfR

readlink -fMac OS X 10.11.6에서는 realpath작동하지 않지만 기본적으로 작동합니다.
Grav

9

내 시스템은 rozcietrzewiaczrealpath 에서 제안한대로 없습니다 .

readlink명령을 사용하여이를 수행 할 수 있습니다 . 구문 분석 which또는 다른 솔루션에 비해이 방법을 사용 하면 경로의 일부 나 실행 된 파일 이름이 심볼릭 링크 인 경우에도 실제 파일이있는 디렉토리를 찾을 수 있다는 장점 이 있습니다.

MYDIR="$(dirname "$(readlink -f "$0")")"

그런 다음 텍스트 파일을 다음과 같은 변수로 읽을 수 있습니다.

TEXTFILE="$(<$MYDIR/textfile)"

@rozcietrzewiacz : 나는 실제로 당신의 which제안 만을 말하는 것이 아닙니다 . 이에 대한 일반적인 솔루션 중 하나를 단지 포함 dirname또는 조합 cdpwd서브 쉘에서합니다. Readlink는 여기에 장점이 있습니다. 어쨌든 realpath거의 래퍼 일 것 같습니다 readlink -f.
Caleb

와 어떻게 realpath다른지 모르겠습니다 readlink -f. 나는 그것이 나에게 동일한 결과를주는 것을 볼 수있다 which.
rozcietrzewiacz

있다는 사실을 양지해야합니다 readlink -f(GNU의로 coreutils에서)이 존재하는 경로의 마지막 요소를 필요로하지 않습니다, readlink -e않지만, 지원하지 않습니다 busybox readlink의 모방 행동, -e자신의 -f옵션을 선택합니다.
dragon788

8

$0스크립트에서 스크립트의 전체 경로가되며 전체 경로를 dirname가져와 디렉토리 만 제공하므로 텍스트 파일을 cat하기 위해이 작업을 수행 할 수 있습니다.

$ cat "$(dirname -- "$0")/textfile"

이것이없이 작동하는 것처럼 보이지만 realpath $0" $0스크립트에서 스크립트의 전체 경로가 될 것 "이라고 말하는 것은 잘못입니다 .
rozcietrzewiacz

@roz 어떤 방법으로?
Michael Mrozek

1
$0실행 된 명령입니다 (예 :) ../script.sh.
rozcietrzewiacz

따라서 실제로 $(dirname "$0")는 절대 경로가 아니라 호출 된 명령의 일부로 스크립트 의 상대 경로를 반환합니다 . 이로 인해 실행 중에 디렉토리를 변경하는 스크립트에서 문제가 발생할 수 있습니다.
rozcietrzewiacz 1

@roz Ah, 흥미 롭습니다. 그래서 이름으로 경로에서 무언가를 호출하기 때문에 여기에서 문제가 발생하지는 않지만 다른 것을 깨뜨릴 것이라고 생각합니다. 감사합니다
Michael Mrozek

4

이것을 스크립트 상단에 넣을 수 있습니다.

cd "${BASH_SOURCE%/*}" || exit

BASH_SOURCE 내부 bash 변수는 실제로 경로 이름의 배열입니다. "$ BASH_SOURCE"와 같은 간단한 문자열로 확장하면 현재 실행중인 함수 또는 스크립트의 경로 이름 인 첫 번째 요소를 얻게됩니다.

출처 : http://mywiki.wooledge.org/BashFAQ/028


2

나는 이것을 시도하고 realpath는 나를 위해 작동하지 않았다. 내가 함께했던 해결책은 다음과 같습니다.

SCRIPTDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )

지금까지 잘 작동했습니다. 접근 방식에 잠재적 인 문제가 있는지 알고 싶습니다.


1
좋지만 심볼릭 링크를 따르지 않습니다. 이것을보십시오 :SCRIPT_DIR="$( cd "$(dirname "$( readlink -f ${BASH_SOURCE[0]} )")" >/dev/null 2>&1 && pwd)"
OronNavon

1

나는 사용한다:

#! /bin/sh -
dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P) || exit
dosomethingwith "${dir%/}/some-file"

POSIX이며 dirname이 $0개행 문자로 끝나지 않고 설정 되지 않았 -거나 $CDPATH설정되지 않은 한 (그리고 스크립트가 조회되지 않은 경우 몇 가지 다른 경우$PATH ) 작동합니다.


0

나는 항상 whichPATH에서 실행 파일의 전체 경로를 찾는 데 사용 합니다. 예를 들어 :

which python

이것을 dirname명령 과 결합하면 다음을 얻습니다.

wp=`which python`
dn=`dirname $wp`
ls $dn
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.