이 SO 게시물("콜론이 포함된 bash 연관 배열 키 문자열에서 오류가 발생함")에 설명된 것과 동일한 문제가 있습니다.https://stackoverflow.com/q/40406187/10639803
해결책은 사용하는 것이지만 declare -A
일단 이렇게 하면 연관 배열이 더 이상 전역적이지 않습니다.
방법이 있나요?declare -A
그리고글로벌하게?
업데이트: 여기에 설명된 대로 시도했습니다 declare -gA
.https://stackoverflow.com/a/21151984/10639803하지만 어떤 이유로든 작동하지 않습니다. 연관 배열(해시맵)을 채우는 루프를 종료하자마자 배열이 설정 해제됩니다.
실제 bash 코드는 다음과 같습니다(루프 내부의 echo 명령은 값이 실제로 추출되고 할당되었는지 확인하기 위한 것입니다).
declare -gA HOSTS_START_MAP
find "$TEMP" -type f -name "debug.log*" -exec grep -F "STARTING HOST " {} \; |
while IFS= read -r HOST_START_LINE; do
if [[ $HOST_START_LINE =~ (.*)(DEBUG)(.*)(STARTING HOST)([ 0-9]*)(.*)(CALCULATION) ]]
then
HOST_START_TIME=$(echo "${BASH_REMATCH[1]}" | xargs)
HOST_NAME=$(echo "${BASH_REMATCH[6]}" | xargs)
# echo ">$HOST_NAME< ... >$HOST_START_TIME<"
HOSTS_START_MAP[$HOST_NAME]=$HOST_START_TIME
# echo $HOST_NAME --- ${HOSTS_START_MAP[$HOST_NAME]}
fi
done
echo ${#HOSTS_START_MAP[@]}
for MYKEY in "${!HOSTS_START_MAP[@]}"; do echo $MYKEY --- ${HOSTS_START_MAP[@]}; done
답변1
보고 있는 문제는 변수 선언과 관련이 없습니다. 하위 쉘에서 변수를 설정하고 해당 값을 상위 쉘에서 사용할 수 있기를 기대하기 때문입니다.
코드와 동일한 구조이지만 훨씬 간단한 예를 사용하여 여기에서 이 효과를 볼 수 있습니다.
a=""
echo find | while read item; do a="$item"; done
echo "a=$a"
다행히도 사용할 때 bash
코드를 다른 모양으로 다시 작성하여 사용할 수 있는 빠른 솔루션이 있습니다.
a=""
while read item; do a="$item"; done < <( echo find )
echo "a=$a"
실제 코드에서는 처리되지 않은 입력을 수신하는지 while IFS= read -r item
확인하는 데 사용됩니다 item
. 예제에서 명확성을 보장하기 위해 보호 기능을 생략했습니다.
이 답변에 대한 의견에서 코드의 수정된 버전을 요청했습니다. 테스트할 수 없기 때문에 처음에 여기에 넣는 것을 주저했지만 다음과 같아야 합니다.
#!/bin/bash
#
declare -gA HOSTS_START_MAP
while IFS= read -r HOST_START_LINE; do
if [[ $HOST_START_LINE =~ (.*)(DEBUG)(.*)(STARTING HOST)([ 0-9]*)(.*)(CALCULATION) ]]
then
HOST_START_TIME=$(echo "${BASH_REMATCH[1]}" | xargs)
HOST_NAME=$(echo "${BASH_REMATCH[6]}" | xargs)
# echo ">$HOST_NAME< ... >$HOST_START_TIME<"
HOSTS_START_MAP[$HOST_NAME]=$HOST_START_TIME
# echo $HOST_NAME --- ${HOSTS_START_MAP[$HOST_NAME]}
fi
done < <( find "$TEMP" -type f -name "debug.log*" -exec grep -F "STARTING HOST " {} \; )
echo ${#HOSTS_START_MAP[@]}
for MYKEY in "${!HOSTS_START_MAP[@]}"; do echo $MYKEY --- ${HOSTS_START_MAP[@]}; done