Bash 스크립트에서 스크립트 파일 이름을 어떻게 알 수 있습니까?
스크립트 자체 내에서 Bash 스크립트 파일의 이름을 어떻게 확인할 수 있습니까?
내 스크립트가 file runme.sh
에있는 것처럼 하드 코딩하지 않고 "You are running runme.sh"메시지를 표시하려면 어떻게해야합니까?
me=`basename "$0"`
일반적으로 원하는 것이 아닌 symlink 1을 읽으 려면 (보통 이러한 방식으로 사용자를 혼동하지 않으려는 경우) 다음을 시도하십시오.
me="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")"
IMO, 그것은 혼란스러운 출력을 생성합니다. "foo.sh를 실행했지만 bar.sh를 실행하고 있다는 뜻입니다!? 버그 일 것입니다!" 게다가 다른 이름의 심볼릭 링크를 사용하는 목적 중 하나는 이름에 따라 다른 기능을 제공하는 것입니다 (일부 플랫폼에서는 gzip 및 gunzip을 생각해보십시오).
1 즉, 사용자 foo.sh
가 실제로에 대한 심볼릭 링크를 실행할 때 심볼릭 링크를 bar.sh
확인하려면 . bar.sh
대신 확인 된 이름을 사용하려고합니다 foo.sh
.
# ------------- 스크립트 ------------- #
#!/bin/bash
echo
echo "# arguments called with ----> ${@} "
echo "# \$1 ----------------------> $1 "
echo "# \$2 ----------------------> $2 "
echo "# path to me ---------------> ${0} "
echo "# parent path --------------> ${0%/*} "
echo "# my name ------------------> ${0##*/} "
echo
exit
# ------------- 호출 됨 ------------- #
# 다음 줄에서 첫 번째 인수는 double 내에서 호출됩니다.
두 단어를 포함하므로 # 및 작은 따옴표
$ /misc/shell_scripts/check_root/show_parms.sh " '안녕하세요'" " '윌리엄'"
# ------------- 결과 ------------- #
# ---> 'hello there' 'william'으로 호출되는 인수
# $ 1 ----------------------> '안녕하세요'
# $ 2 ----------------------> 'william'
# 내 경로 --------------> /misc/shell_scripts/check_root/show_parms.sh
# 부모 경로 -------------> / misc / shell_scripts / check_root
# 내 이름 -----------------> show_parms.sh
# ------------- END ------------- #
와 bash는> = 3 개 다음 작품 :
$ ./s
0 is: ./s
BASH_SOURCE is: ./s
$ . ./s
0 is: bash
BASH_SOURCE is: ./s
$ cat s
#!/bin/bash
printf '$0 is: %s\n$BASH_SOURCE is: %s\n' "$0" "$BASH_SOURCE"
$BASH_SOURCE
스크립트를 소싱 할 때 정답을 제공합니다.
그러나 여기에는 경로가 포함되어 있으므로 스크립트 파일 이름 만 가져 오려면 다음을 사용하십시오.
$(basename $BASH_SOURCE)
스크립트 이름에 공백이 있다면 더 강력한 방법은 사용하는 것입니다 "$0"
또는 "$(basename "$0")"
- 또는 맥 OS에 : "$(basename \"$0\")"
. 이렇게하면 이름이 어떤 식 으로든 왜곡되거나 해석되는 것을 방지 할 수 있습니다. 일반적으로 셸에서 변수 이름을 항상 큰 따옴표로 묶는 것이 좋습니다.
경로없이 원하는 경우 다음을 사용합니다. ${0##*/}
Chris Conway에 대답하려면 Linux에서 (적어도) 다음을 수행합니다.
echo $(basename $(readlink -nf $0))
readlink는 심볼릭 링크의 값을 인쇄합니다. 심볼릭 링크가 아닌 경우 파일 이름을 인쇄합니다. -n은 개행을 인쇄하지 않도록 지시합니다. -f는 링크를 완전히 따르도록 지시합니다 (심볼릭 링크가 다른 링크에 대한 링크 인 경우 해당 링크도 해결됩니다).
이 줄은 파일이 소스인지 스크립트로 실행되는지에 관계없이 항상 작동하는 것으로 나타났습니다.
echo "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"
readlink
위의 경로에서 심볼릭 링크를 따르려면 재귀 적 또는 비재 귀적으로 사용하십시오.
한 줄짜리가 작동하는 이유는 BASH_SOURCE
환경 변수와 그에 상응하는 FUNCNAME
.
BASH_SOURCE
멤버가 FUNCNAME 배열 변수의 해당 쉘 함수 이름이 정의 된 소스 파일 이름 인 배열 변수입니다. $ {FUNCNAME [$ i]} 셸 함수는 $ {BASH_SOURCE [$ i]} 파일에 정의되어 있으며 $ {BASH_SOURCE [$ i + 1]}에서 호출됩니다.
FUNCNAME
현재 실행 호출 스택에있는 모든 셸 함수의 이름을 포함하는 배열 변수입니다. 인덱스가 0 인 요소는 현재 실행중인 모든 쉘 함수의 이름입니다. 가장 아래에있는 요소 (인덱스가 가장 높은 요소)는 "main"입니다. 이 변수는 쉘 함수가 실행 중일 때만 존재합니다. FUNCNAME에 대한 할당은 효과가 없으며 오류 상태를 반환합니다. FUNCNAME이 설정되지 않은 경우 이후에 재설정 되더라도 특수 속성이 손실됩니다.
이 변수는 BASH_LINENO 및 BASH_SOURCE와 함께 사용할 수 있습니다. FUNCNAME의 각 요소에는 BASH_LINENO 및 BASH_SOURCE에 해당 요소가있어 호출 스택을 설명합니다. 예를 들어 $ {FUNCNAME [$ i]}은 $ {BASH_SOURCE [$ i + 1]} 파일에서 $ {BASH_LINENO [$ i]} 번 줄에서 호출되었습니다. 호출자 내장은이 정보를 사용하여 현재 호출 스택을 표시합니다.
[출처 : Bash 매뉴얼]
이 답변은 그들이 언급 한 경우에 맞지만 'source'키워드를 사용하여 다른 스크립트에서 스크립트를 실행하면 여전히 문제가 있습니다 (동일한 쉘에서 실행되도록). 이 경우 호출 스크립트의 $ 0를 얻습니다. 그리고이 경우에는 스크립트 자체의 이름을 얻을 수 없다고 생각합니다.
이것은 극단적 인 경우이며 너무 심각하게 받아 들여서는 안됩니다. 다른 스크립트에서 직접 스크립트를 실행하는 경우 ( 'source'없이) $ 0 사용이 작동합니다.
Re : 위의 Tanktalus의 (허용되는) 답변, 약간 더 깨끗한 방법은 다음을 사용하는 것입니다.
me=$(readlink --canonicalize --no-newline $0)
스크립트가 다른 bash 스크립트에서 제공된 경우 다음을 사용할 수 있습니다.
me=$(readlink --canonicalize --no-newline $BASH_SOURCE)
사용자에게 피드백을 제공하는 것이 목적이라면 심볼릭 링크를 역 참조하는 것이 혼란 스러울 것이라는 데 동의하지만, 스크립트 나 다른 파일에 정식 이름을 가져와야하는 경우가 있으며 이것이 가장 좋은 방법 인 imo입니다.
확장명이없는 파일 이름에 대해 몇 가지 의견을 물었으므로 다음은이를 수행하는 방법의 예입니다.
FileName=${0##*/}
FileNameWithoutExtension=${FileName%.*}
즐겨!
호출 쉘 스크립트가 다음과 같은 경우
/home/mike/runme.sh
$ 0은 전체 이름입니다.
/home/mike/runme.sh
basename $ 0은 기본 파일 이름을 얻습니다.
runme.sh
이 기본 이름을 다음과 같은 변수에 넣어야합니다.
filename=$(basename $0)
추가 텍스트를 추가하십시오
echo "You are running $filename"
그래서 당신의 스크립트는
/home/mike/runme.sh
#!/bin/bash
filename=$(basename $0)
echo "You are running $filename"
$ 0를 사용하여 스크립트 이름 (전체 경로 포함)을 결정할 수 있습니다. 스크립트 이름을 얻으려면 해당 변수를
basename $0
this="$(dirname "$(realpath "$BASH_SOURCE")")"
이것은 심볼릭 링크를 해결하고 (realpath가 그렇게 함), 공백을 처리하고 (이중 따옴표가이를 수행), 소싱 (. ./myscript)되거나 다른 스크립트 ($ BASH_SOURCE가이를 처리 함)에 의해 호출 된 경우에도 현재 스크립트 이름을 찾습니다. 결국 재사용을 위해 또는 다른 곳에서 쉽게 복사하기 위해 환경 변수에 저장하는 것이 좋습니다 (this =) ...
를 bash
사용하여 스크립트 파일 이름을 가져올 수 있습니다 $0
. 일반적으로 $1
, $2
등 액세스 CLI 인수에 있습니다. 마찬가지로 $0
스크립트를 트리거하는 이름 (스크립트 파일 이름)에 액세스하는 것입니다.
#!/bin/bash
echo "You are running $0"
...
...
/path/to/script.sh
다음 과 같은 경로로 스크립트를 호출하면 경로와 $0
함께 파일 이름도 제공됩니다. 이 경우 $(basename $0)
스크립트 파일 이름 만 가져와야합니다.
Bill Hernandez에게 정보를 제공합니다. 채택하고있는 몇 가지 환경 설정을 추가했습니다.
#!/bin/bash
function Usage(){
echo " Usage: show_parameters [ arg1 ][ arg2 ]"
}
[[ ${#2} -eq 0 ]] && Usage || {
echo
echo "# arguments called with ----> ${@} "
echo "# \$1 -----------------------> $1 "
echo "# \$2 -----------------------> $2 "
echo "# path to me ---------------> ${0} " | sed "s/$USER/\$USER/g"
echo "# parent path --------------> ${0%/*} " | sed "s/$USER/\$USER/g"
echo "# my name ------------------> ${0##*/} "
echo
}
건배
$0
질문에 대답하지 않습니다 (내가 이해 한대로). 데모 :
$ cat script.sh #! / bin / sh echo`basename $ 0` $ ./script.sh script.sh $ ln script.sh linktoscript $ ./linktoscript linktoscript
어떻게 ./linktoscript
인쇄 할 수 script.sh
있습니까?
[편집] 위의 주석에서 @ephemient에 따라 심볼릭 링크가 인위적으로 보일 수 있지만 $0
파일 시스템 리소스를 나타내지 않도록 조작하는 것이 가능합니다. OP는 그가 원하는 것에 대해 약간 모호합니다.
echo "$(basename "`test -L ${BASH_SOURCE[0]} \
&& readlink ${BASH_SOURCE[0]} \
|| echo ${BASH_SOURCE[0]}`")"
echo "$ 0 실행 중"
DIRECTORY=$(cd `dirname $0` && pwd)
I got the above from another Stack Overflow question, Can a Bash script tell what directory it's stored in?, but I think it's useful for this topic as well.
Here is what I came up with, inspired by Dimitre Radoulov's answer (which I upvoted, by the way).
script="$BASH_SOURCE"
[ -z "$BASH_SOURCE" ] && script="$0"
echo "Called $script with $# argument(s)"
regardless of the way you call your script
. path/to/script.sh
or
./path/to/script.sh
Short, clear and simple, in my_script.sh
#!/bin/bash
running_file_name=$(basename "$0")
echo "You are running '$running_file_name' file."
Out put:
./my_script.sh
You are running 'my_script.sh' file.
somthing like this?
export LC_ALL=en_US.UTF-8
#!/bin/bash
#!/bin/sh
#----------------------------------------------------------------------
start_trash(){
ver="htrash.sh v0.0.4"
$TRASH_DIR # url to trash $MY_USER
$TRASH_SIZE # Show Trash Folder Size
echo "Would you like to empty Trash [y/n]?"
read ans
if [ $ans = y -o $ans = Y -o $ans = yes -o $ans = Yes -o $ans = YES ]
then
echo "'yes'"
cd $TRASH_DIR && $EMPTY_TRASH
fi
if [ $ans = n -o $ans = N -o $ans = no -o $ans = No -o $ans = NO ]
then
echo "'no'"
fi
return $TRUE
}
#-----------------------------------------------------------------------
start_help(){
echo "HELP COMMANDS-----------------------------"
echo "htest www open a homepage "
echo "htest trash empty trash "
return $TRUE
} #end Help
#-----------------------------------------------#
homepage=""
return $TRUE
} #end cpdebtemp
# -Case start
# if no command line arg given
# set val to Unknown
if [ -z $1 ]
then
val="*** Unknown ***"
elif [ -n $1 ]
then
# otherwise make first arg as val
val=$1
fi
# use case statement to make decision for rental
case $val in
"trash") start_trash ;;
"help") start_help ;;
"www") firefox $homepage ;;
*) echo "Sorry, I can not get a $val for you!";;
esac
# Case stop
참고URL : https://stackoverflow.com/questions/192319/how-do-i-know-the-script-file-name-in-a-bash-script
'program tip' 카테고리의 다른 글
Java에서 일반 유형의 인스턴스를 만드시겠습니까? (0) | 2020.10.04 |
---|---|
대신 아이콘에 태그를 (0) | 2020.10.04 |
명령 줄 인수를 읽고 처리하는 방법은 무엇입니까? (0) | 2020.10.03 |
먼저 닫아야하는이 명령과 연결된 열린 DataReader가 이미 있습니다. (0) | 2020.10.03 |
Android 애플리케이션에서 인터넷에 액세스하려면 어떤 권한이 필요합니까? (0) | 2020.10.03 |