해당 스크립트 내 에서 Bash 스크립트가 있는 디렉토리의 경로를 얻으려면 어떻게합니까 ?
Bash 스크립트를 다른 응용 프로그램의 실행기로 사용하고 싶습니다. 작업 디렉토리를 Bash 스크립트가있는 디렉토리로 변경하고 싶으므로 해당 디렉토리의 파일을 다음과 같이 조작 할 수 있습니다.
$ ./application
답변
#!/bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
어디에서 스크립트를 호출하든 스크립트의 전체 디렉토리 이름을 제공하는 유용한 one-liner입니다.
스크립트를 찾는 데 사용 된 경로의 마지막 구성 요소가 심볼릭 링크가 아닌 한 (디렉토리 링크는 정상 임) 작동합니다. 스크립트 자체에 대한 링크도 해결하려면 여러 줄 솔루션이 필요합니다.
#!/bin/bash
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
이 마지막 하나는 별명의 조합으로 작동 source
, bash -c
심볼릭 링크 등
주의 : 당신이 경우에 cd
이 코드를 실행하기 전에 다른 디렉토리로, 결과가 잘못 될 수 있습니다!
또한 사용자가 cd를 현명하게 재정 의하여 출력을 stderr로 리디렉션하는 경우 ( Mac에서 호출 할 때와 같은 이스케이프 시퀀스 포함) $CDPATH
gotchas 및 stderr 출력 부작용 update_terminal_cwd >&2
에주의하십시오. 명령 >/dev/null 2>&1
끝에 추가하면 cd
두 가지 가능성이 모두 해결됩니다.
작동 방식을 이해하려면 다음과 같은 더 자세한 양식을 실행하십시오.
#!/bin/bash
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
TARGET="$(readlink "$SOURCE")"
if [[ $TARGET == /* ]]; then
echo "SOURCE '$SOURCE' is an absolute symlink to '$TARGET'"
SOURCE="$TARGET"
else
DIR="$( dirname "$SOURCE" )"
echo "SOURCE '$SOURCE' is a relative symlink to '$TARGET' (relative to '$DIR')"
SOURCE="$DIR/$TARGET" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
fi
done
echo "SOURCE is '$SOURCE'"
RDIR="$( dirname "$SOURCE" )"
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
if [ "$DIR" != "$RDIR" ]; then
echo "DIR '$RDIR' resolves to '$DIR'"
fi
echo "DIR is '$DIR'"
그리고 다음과 같이 인쇄됩니다.
SOURCE './scriptdir.sh' is a relative symlink to 'sym2/scriptdir.sh' (relative to '.')
SOURCE is './sym2/scriptdir.sh'
DIR './sym2' resolves to '/home/ubuntu/dotfiles/fo fo/real/real1/real2'
DIR is '/home/ubuntu/dotfiles/fo fo/real/real1/real2'
답변
사용 dirname "$0"
:
#!/bin/bash
echo "The script you are running has basename `basename "$0"`, dirname `dirname "$0"`"
echo "The present working directory is `pwd`"
사용 pwd
당신이이에 포함 된 디렉토리에서 스크립트를 실행하지 않으면 작동하지 않습니다 만.
[matt@server1 ~]$ pwd
/home/matt
[matt@server1 ~]$ ./test2.sh
The script you are running has basename test2.sh, dirname .
The present working directory is /home/matt
[matt@server1 ~]$ cd /tmp
[matt@server1 tmp]$ ~/test2.sh
The script you are running has basename test2.sh, dirname /home/matt
The present working directory is /tmp
답변
이 dirname
명령은 가장 기본적이며 단순히 $0
(스크립트 이름) 변수 에서 파일 이름까지의 경로를 구문 분석합니다 .
dirname "$0"
그러나 매트 b가 지적했듯이 반환되는 경로는 스크립트 호출 방법에 따라 다릅니다. pwd
스크립트가있는 디렉토리가 아니라 현재 디렉토리 만 알려주기 때문에 작업을 수행하지 않습니다. 또한 스크립트에 대한 심볼릭 링크가 실행되면 (아마도 상대적인) 경로를 얻게됩니다 실제 스크립트가 아닌 링크가있는 위치
다른 사람들은 readlink
명령 을 언급 했지만 가장 간단하게 다음을 사용할 수 있습니다.
dirname "$(readlink -f "$0")"
readlink
스크립트 경로를 파일 시스템의 루트에서 절대 경로로 해석합니다. 따라서 단일 또는 이중 도트, 물결표 및 / 또는 기호 링크가 포함 된 경로는 전체 경로로 해석됩니다.
다음은 이들 각각을 보여주는 스크립트입니다 whatdir.sh
.
#!/bin/bash
echo "pwd: `pwd`"
echo "\$0: $0"
echo "basename: `basename $0`"
echo "dirname: `dirname $0`"
echo "dirname/readlink: $(dirname $(readlink -f $0))"
상대 경로를 사용하여 내 홈 디렉토리 에서이 스크립트를 실행하십시오.
>>>$ ./whatdir.sh
pwd: /Users/phatblat
$0: ./whatdir.sh
basename: whatdir.sh
dirname: .
dirname/readlink: /Users/phatblat
다시 말하지만 스크립트의 전체 경로를 사용하십시오.
>>>$ /Users/phatblat/whatdir.sh
pwd: /Users/phatblat
$0: /Users/phatblat/whatdir.sh
basename: whatdir.sh
dirname: /Users/phatblat
dirname/readlink: /Users/phatblat
이제 디렉토리 변경 :
>>>$ cd /tmp
>>>$ ~/whatdir.sh
pwd: /tmp
$0: /Users/phatblat/whatdir.sh
basename: whatdir.sh
dirname: /Users/phatblat
dirname/readlink: /Users/phatblat
마지막으로 심볼릭 링크를 사용하여 스크립트를 실행하십시오.
>>>$ ln -s ~/whatdir.sh whatdirlink.sh
>>>$ ./whatdirlink.sh
pwd: /tmp
$0: ./whatdirlink.sh
basename: whatdirlink.sh
dirname: .
dirname/readlink: /Users/phatblat
답변
pushd . > /dev/null
SCRIPT_PATH="${BASH_SOURCE[0]}"
if ([ -h "${SCRIPT_PATH}" ]); then
while([ -h "${SCRIPT_PATH}" ]); do cd `dirname "$SCRIPT_PATH"`;
SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`; done
fi
cd `dirname ${SCRIPT_PATH}` > /dev/null
SCRIPT_PATH=`pwd`;
popd > /dev/null
다음을 포함한 모든 버전에서 작동
- 다중 깊이 소프트 링크를 통해 호출 될 때
- 때 파일
- 스크립트 ”
source
“일명.
(점) 연산자로 스크립트를 호출 한 경우 $0
호출자가 arg 를 수정 한 경우"./script"
"/full/path/to/script"
"/some/path/../../another/path/script"
"./some/folder/script"
또는, bash는 스크립트 자체가 경우 상대 심볼릭 링크 당신이 원하는 의 전체 경로를 그것을 따라 반환이 연결된에 스크립트 :
pushd . > /dev/null
SCRIPT_PATH="${BASH_SOURCE[0]}";
if ([ -h "${SCRIPT_PATH}" ]) then
while([ -h "${SCRIPT_PATH}" ]) do cd `dirname "$SCRIPT_PATH"`; SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`; done
fi
cd `dirname ${SCRIPT_PATH}` > /dev/null
SCRIPT_PATH=`pwd`;
popd > /dev/null
SCRIPT_PATH
어떻게 호출 되든 전체 경로로 제공됩니다.
스크립트 시작시이 위치를 찾으십시오.
이 설명과 코드는 GPL2.0 이상 또는 CC-SA 3.0 (CreativeCommons Share Alike) 이상에서 선택 가능한 라이센스 인 Copyleft입니다. (c) 2008. 모든 권리 보유. 어떤 종류의 보증도하지 않습니다. 경고를 받았습니다.
http://www.gnu.org/licenses/gpl-2.0.txt
http://creativecommons.org/licenses/by-sa/3.0/
18eedfe1c99df68dc94d4a94712a71aaa8e1e9e36cacf421b9463dd2bbaa02906d0d6656
답변
답변
당신은 사용할 수 있습니다 $BASH_SOURCE
:
#!/bin/bash
scriptdir=`dirname "$BASH_SOURCE"`
Bash 확장이므로 사용 #!/bin/bash
하지 않아야 #!/bin/sh
합니다.
답변
이것은해야합니다 :
DIR="$(dirname "$(readlink -f "$0")")"
이것은 경로의 심볼릭 링크 및 공백과 함께 작동합니다.
dirname
및에 대한 매뉴얼 페이지를 참조하십시오 readlink
.
댓글 트랙에서 Mac OS에서는 작동하지 않는 것 같습니다. 왜 그런지 모르겠습니다. 어떤 제안?