스크립트 내에서 소스 tcsh 또는 bash 쉘 스크립트의 경로를 결정하는 방법

스크립트 내에서 소스 tcsh 또는 bash 쉘 스크립트의 경로를 결정하는 방법

어떤 방법이 있나요?원천쉘 스크립트가 자체 경로를 찾습니까? 내 주요 관심사는 bash내 동료 중 일부가 tcsh.

소싱으로 인해 현재 셸에서 명령이 실행되므로 여기서는 운이 좋지 않을 수 있습니다. 따라서 $0여전히 소스 스크립트가 아닌 현재 셸을 호출합니다. 가장 좋은 아이디어는 source $script $script첫 번째 위치 매개변수에 필요한 정보를 포함시키는 것입니다. 누구든지 더 좋은 방법이 있습니까?

분명히 말하자면 나는구입스크립트를 실행하는 대신:

source foo.bash

답변1

에서는 파일 tcsh이 원본이거나 파일이 실행된 경우 $_스크립트 시작 부분에 해당 위치가 포함됩니다 .$0

#!/bin/tcsh
set sourced=($_)
if ("$sourced" != "") then
    echo "sourced $sourced[2]"
endif
if ("$0" != "tcsh") then
    echo "run $0"
endif

큰 타격을 받은 경우:

#!/bin/bash
[[ $0 != $BASH_SOURCE ]] && echo "Script is being sourced" || echo "Script is being run"

답변2

변수를 활용하시면 될 것 같아요 $BASH_SOURCE. 실행 경로를 반환합니다.

예시 스크립트:

인쇄 스크립트 경로.sh:

#!/usr/bin/env bash

echo "$BASH_SOURCE"

실행 가능하게 만드세요:

chmod +x print_script_path.sh

이 스크립트의 다양한 위치에 대해 예제가 실행되고 출력됩니다.

pbm@tauri ~ $ /home/pbm/print_script_path.sh 
/home/pbm/print_script_path.sh
pbm@tauri ~ $ ./print_script_path.sh
./print_script_path.sh
pbm@tauri ~ $ source /home/pbm/print_script_path.sh 
/home/pbm/print_script_path.sh
pbm@tauri ~ $ source ./print_script_path.sh
./print_script_path.sh

그럼 다음으로 경로가 상대 경로인지 확인해야 합니다. 상대적인 것이 아니라면 모든 것이 괜찮을 것입니다. 그렇다면 경로를 확인 pwd하고 및 /와 연결하는 데 사용할 수 있습니다 $BASH_SOURCE.

답변3

이 솔루션은 tcsh가 아닌 bash에서만 작동합니다. ${BASH_SOURCE[0]}함수 내에서 경로를 찾으려고 하면 일반적으로 제공되는 답변이 작동하지 않습니다.

나는 이 줄이 파일이 소스 파일로 실행되는지 아니면 스크립트로 실행되는지에 관계없이 항상 작동한다는 것을 발견했습니다.

echo "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"

readlink재귀적으로 또는 비재귀적으로 심볼릭 링크를 따르 려면 위에서 얻은 경로를 사용하세요.

큰따옴표는 경로의 공백이 결과를 배열로 분할하는 것을 방지하며 에 대해서뿐만 아니라 echo사용되는 모든 컨텍스트에도 필요합니다. 배열 항목 사이에 단일 공백이 삽입 되므로 echo경로에 두 개 이상의 연속 공백이 없으면 차이가 숨겨집니다.

다음은 이를 다른 제안 솔루션과 비교하는 스크립트입니다. source test1/test2/test_script.sh또는 이라고 부르세요 bash test1/test2/test_script.sh.

#
# Location: test1/test2/test_script.sh
#
echo $0
echo $_
echo "${BASH_SOURCE}"
echo "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"

cur_file="${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"
cur_dir="$(dirname "${cur_file}")"
source "${cur_dir}/func_def.sh"

function test_within_func_inside {
    echo "${BASH_SOURCE}"
    echo "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"
}

echo "Testing within function inside"
test_within_func_inside

echo "Testing within function outside"
test_within_func_outside
#
# Location: test1/test2/func_def.sh
#
function test_within_func_outside {
    echo "${BASH_SOURCE}"
    echo "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"
}

한 줄의 코드가 작동하는 이유는 BASH_SOURCE환경 변수 및 관련 변수의 사용으로 설명할 수 있습니다 FUNCNAME.

BASH_SOURCE

FUNCNAME 배열 변수에 해당 쉘 함수 이름을 정의하는 소스 파일 이름이 멤버인 배열 변수입니다. 쉘 함수 ${FUNCNAME[$i]}는 ${BASH_SOURCE[$i]} 파일에 정의되어 있으며 ${BASH_SOURCE[$i+1]}에서 호출됩니다.

기능 이름

현재 실행 중인 호출 스택에 있는 모든 셸 함수의 이름을 포함하는 배열 변수입니다. 인덱스 0의 요소는 현재 실행 중인 쉘 함수의 이름입니다. 맨 아래 요소(인덱스가 가장 높은 요소)는 "main"입니다. 이 변수는 쉘 함수가 실행될 때만 존재합니다. FUNCNAME에 대한 할당이 잘못되었으며 오류 상태를 반환합니다. FUNCNAME이 설정되지 않으면 나중에 재설정되더라도 특수 속성이 손실됩니다.

이 변수는 BASH_LINENO 및 BASH_SOURCE와 함께 사용할 수 있습니다. FUNCNAME의 각 요소에는 BASH_LINENO 및 BASH_SOURCE에 호출 스택을 설명하는 해당 요소가 있습니다. 예를 들어 ${FUNCNAME[$i]}는 ${BASH_SOURCE[$i+1]} 파일의 줄 번호 ${BASH_LINENO[$i]}에서 호출됩니다. 내장 호출자는 이 정보를 사용하여 현재 호출 스택을 표시합니다.

[출처: Bash 매뉴얼]

답변4

철저함과 검색자를 위해 그것이 바로 목적입니다... 커뮤니티 위키이므로 다른 쉘에 상응하는 항목을 자유롭게 추가하십시오(분명히 $BASH_SOURCE는 다를 것입니다).

테스트.sh:

#! /bin/sh
called=$_
echo $called
echo $_
echo $0
echo $BASH_SOURCE

test2.sh:

#! /bin/sh
source ./test.sh

큰 타격:

$./test2.sh
./test2.sh
./test2.sh
./test2.sh
./test.sh
$ sh ./test2.sh
/bin/sh
/bin/sh
./test2.sh
./test.sh

스프린트

$./test2.sh
./test2.sh
./test2.sh
./test2.sh

$/bin/sh ./test2.sh
/bin/sh
/bin/sh
./test2.sh

$

지쉬

$ ./test2.sh
./test.sh
./test.sh
./test.sh

$ zsh test.sh

echo
test.sh

$

관련 정보