![-A MYASSOCIATIVARRY를 전 세계적으로 선언하는 방법은 무엇입니까? [복사]](https://linux55.com/image/164645/-A%20MYASSOCIATIVARRY%EB%A5%BC%20%EC%A0%84%20%EC%84%B8%EA%B3%84%EC%A0%81%EC%9C%BC%EB%A1%9C%20%EC%84%A0%EC%96%B8%ED%95%98%EB%8A%94%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%20%5B%EB%B3%B5%EC%82%AC%5D.png)
이 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