이 Bash 스크립트에서 "else" 분기(배열을 순회하는 루프)가 실행되지 않는 이유는 무엇입니까?

이 Bash 스크립트에서 "else" 분기(배열을 순회하는 루프)가 실행되지 않는 이유는 무엇입니까?

다음 코드 ~/Downloads. ./script.sh. 사용자가 불완전한 이름을 제출하더라도 이를 찾아냅니다.

#!/usr/bin/bash

echo -e "\nGive me the name of a nonexitent directory and I will look for it in ~/Downloads?\n"

read word

TOGOs=("$(find ~/Downloads -maxdepth 1 -iname "*$word*" -type d -execdir echo {} + | sed 's;./;/home/smith/Downloads/;g')"
"")
for togo in ${TOGOs[@]}
do
  if [[ $togo != "" ]]; then
    echo $togo
    export togo && cd $togo && return 0
  else
    echo "Haven't found it in ~/Downloads ." && cd ~/Downloads #This line does not work
  fi
done

해당 if부분은 예상대로 작동합니다. 이름/하위 디렉터리의 일부 name 을 지정하면 존재하지 않는 디렉터리를 지정하면 블록의 일부가 실행되지 않습니다 ~/Downloads/. 루프에서 벗어나면 다음과 같이 실행된 부분을 얻을 수 있습니다.elseelse

#!/usr/bin/bash

echo -e "\nGive me the name of a nonexitent directory and I will look for it in ~/Downloads?\n"

read word
TOGO=$(find ~/Downloads -maxdepth 1 -iname "*$word*" -type d -execdir echo {} + | sed 's;./;/home/smith/Downloads/;g')

if [[ $TOGO != "" ]]; then
  echo $TOGO
  export TOGO 
  cd $TOGO && return 0
else

  echo "Haven't found it in ~/Downloads." && cd ~/Downloads
fi

else루프에서 벗어날 때 팔이 실행되는 이유 는 무엇 입니까? 루프를 유지하면서 코드를 어떻게 실행할 수 있나요?

답변1

${TOGOs[@]}배열의 요소를 가져와 공백(기본값으로 가정 IFS)에서 별도의 단어로 분할하고 각 단어를 glob 패턴으로 해석하는 것을 나타냅니다. $var모든 요소를 ​​순서대로 나열한다는 점을 제외하면 스칼라 변수와 동일합니다 .

배열에 빈 요소가 있으면 분할 단계에서 해당 요소가 0 단어 목록으로 바뀌므로 효과적으로 삭제됩니다.

언제나 그렇듯: 변수와 ​​명령 대체에는 큰따옴표를 사용하세요.모르는 경우에는 제외해야 합니다. 배열 요소를 나열하려면 올바른 구문은 입니다 "${TOGOs[@]}". 배열 액세스는 큰따옴표를 능가합니다. 배열의 각 요소는 별도의 단어에 배치됩니다.

그러나 올바른 배열 목록 구문을 사용하면 배열이 구성되는 방식이 이해되지 않기 때문에 도움이 되지 않습니다. 전체 출력을 find단일 배열 요소에 넣습니다. 이 방법으로 출력을 구문 분석할 수 없습니다 find. 파일 이름의 일부인 줄 바꿈과 파일 이름을 구별하는 데 사용되는 줄 바꿈을 구별할 방법이 없습니다 find.

출력을 구문 분석하지 말고 findbash에서 처리하거나 find -exec …Bash에 재귀적 와일드카드를 사용하십시오(를 통해).shopt -s globstar) 필요하지만 사용하고 있기 때문에 find -maxdepth 1실제로는 필요하지 않으며 find실제로 유용한 작업을 수행하지 않습니다.

shopt -s dotglob nullglob
TOGOs=(~/Downloads/*$word*/)
if [[ ${#TOGOs[@]} -eq 0 ]]; then
  echo "Haven't found it in ~/Downloads."
fi
for togo in "${TOGOs[@]}"; do
done

관련 정보