![소스 bash 스크립트에서 변수를 로컬로 만드는 가장 좋은 방법은 무엇입니까?](https://linux55.com/image/70043/%EC%86%8C%EC%8A%A4%20bash%20%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%97%90%EC%84%9C%20%EB%B3%80%EC%88%98%EB%A5%BC%20%EB%A1%9C%EC%BB%AC%EB%A1%9C%20%EB%A7%8C%EB%93%9C%EB%8A%94%20%EA%B0%80%EC%9E%A5%20%EC%A2%8B%EC%9D%80%20%EB%B0%A9%EB%B2%95%EC%9D%80%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
내 컴퓨터에서 일부 장기 실행 작업에 대한 진행 보고서를 생성하는 bash 스크립트가 있습니다. 기본적으로 이 상위 스크립트는 하위 스크립트 목록을 반복합니다(호출 포함 source
). 하위 스크립트는 상위 스크립트에서 사용할 몇 가지 특정 변수를 설정해야 합니다.
오늘 저는 첫 번째 첨자로 설정된 변수가 실수로 두 번째 첨자에서 사용되어 잘못된 출력이 발생하는 버그를 발견했습니다. 이러한 유형의 오류가 발생하지 않도록 방지할 수 있는 확실한 방법이 있습니까?
기본적으로, 제가 source
하위 스크립트일 때 일부 특정 변수를 상위 스크립트에 다시 유지하고 싶습니다. 내 상위 스크립트는 각각의 새로운 하위 스크립트 전에 이러한 특정 변수를 재설정하므로 source
문제가 없습니다. 그러나 일부 하위 스크립트에는 상위 스크립트에 다시 유지되어서는 안되는 로컬로 사용되는 추가 임의 변수가 있을 수 있습니다.
분명히 아래 첨자의 끝에서 이들 각각을 수동으로 설정 해제할 수 있지만, 이들 중 하나를 잊어버리면 오류가 발생하기 쉬운 것 같습니다. 스크립트를 가져오고 특정 변수만 호출된 스크립트에 유지하는 더 적절한 방법이 있습니까 source
?
편집: 명확성을 위해 상위 스크립트의 단순화된 버전은 다음과 같습니다.
echo "<html><body><h1>My jobs</h1>"
FILES=~/confs/*.sh
for f in $FILES; do
# reset variables
name="Unnamed job"
secsSinceActive="Unknown"
statusText="Unknown"
# run the script that checks on the job
source "$f"
# print bit of report
echo "<h3>$name</h3>"
echo "<p>Last active: $secsSinceActive seconds ago</p>"
echo "<p>Status: $statusText</p>"
echo "</body></html>"
아래 첨자 중 하나는 다음과 같습니다.
name="My awesome job"
nowTime=`expr $(date +%s) `
lastActiveTime=`expr $(date +%s -r ~/blah.log)`
secsSinceActive=`expr $nowTime - $lastActiveTime`
currentRaw=$(cat ~/blah.log | grep "Progress" | tail -n 1)
if [ -z "$currentRaw" ]; then
statusText="Not running"
else
statusText="In progress"
fi
$name, $secsSinceActive 및 $statusText 변수는 상위 스크립트에 다시 유지되어야 하지만 다른 모든 변수는 하위 스크립트가 종료되면 사라져야 합니다.
답변1
함수로 가져오려는 전체 스크립트를 래핑하고 함수에서만 사용하려는 선언 앞에 local을 추가한 다음 스크립트 끝에서 함수를 호출합니다.
func () {
local name="My awesome job"
nowTime=`expr $(date +%s) `
lastActiveTime=`expr $(date +%s -r ~/blah.log)`
local secsSinceActive=`expr $nowTime - $lastActiveTime`
currentRaw=$(cat ~/blah.log | grep "Progress" | tail -n 1)
if [ -z "$currentRaw" ]; then
local statusText="Not running"
else
local statusText="In progress"
fi
}
func
답변2
전체 스크립트를 함수로 래핑하는 변형은 source
d 스크립트가 소스 코드 자체를 가져오도록 하는 것입니다.통과하다기능:
bleh.sh
스크립트 를 source
-ing 하자
#!/bin/bash
echo -e "\x1b[34mI am $(basename ${BASH_SOURCE[0]})\x1b[0m"
source blah.sh
echo -e "\x1b[34mStill $(basename ${BASH_SOURCE[0]})\x1b[0m"
echo -e "\x1b[34mA=$A\x1b[0m"
echo -e "\x1b[34mB=$B\x1b[0m"
그리고 d blah.sh
스크립트 source
:
#!/bin/bash
echo -e "\x1b[33mI am $(basename ${BASH_SOURCE[0]})\x1b[0m"
fun() {
local A
local HACK_ACTIVATED=yes
source "$1"
}
(return 0 2>/dev/null) && [ -z "$HACK_ACTIVATED" ] && {
fun "${BASH_SOURCE[0]}"
return
}
echo -e "\x1b[33mStill $(basename ${BASH_SOURCE[0]})\x1b[0m"
A=1
export B=1
echo -e "\x1b[33mA=$A\x1b[0m"
echo -e "\x1b[33mB=$B\x1b[0m"
실행 시 bleh.sh
출력은 다음과 같습니다.
작동 방식:
bleh
소스 의 경우 아직 설정되지 않은 지역 변수 에서 알 수 있듯이 Ⓐ 획득되었으며 Ⓑ 아직 자체 획득되지 않았음을 확인blah.sh
하세요 .blah.sh
fun()
fun()
HACK_ACTIVATED
blah.sh
그런 다음 현재 스크립트를 호출하여fun()
함수에 전달합니다.fun()
로컬로 유지하려는 변수를 로컬 변수로 설정한 다음재귀적으로source
해당 스크립트를 다시 포함합니다(blah.sh
).
(소스인지 확인한 이유는 blah.sh
제 경우에는 스크립트가 독립형으로도 작동하기 때문입니다.)
답변3
Bash에서 변수를 로컬로 만드는 구문은 다음과 같습니다.
local variable_name=
이것이 함수에서 작동한다는 것을 알고 있지만 여러 스크립트에서 어떻게 작동하는지 잘 모르겠습니다.