bash 스크립트를 작성하고 echo 명령을 이해하려고 노력하십시오.

bash 스크립트를 작성하고 echo 명령을 이해하려고 노력하십시오.

저는 bash 스크립팅을 배우고 있는데 스크립트에서 작업하는 동안 스피너를 직접 만들려고 하는 동안 이 코드를 발견했습니다.이 문제:

i=1
sp="/-\|"
echo -n ' '
while true
do
printf "\b${sp:i++%${#sp}:1}"
done

이것이 내가 찾던 것입니다. 연결되지 않고 항목을 제거하고 다음 문자를 에코하는 스피너 유형입니다.$sp

그러나 나는 이것이 어떻게 작동하는지 이해하지 못합니다

printf "\b${sp:i++%${#sp}:1}"

누군가 나를 위해 이것에 대해 자세히 설명하여 무슨 일이 일어나고 있는지 이해할 수 있습니까? 프로그래밍 관점에서 보면 삼항 for 루프처럼 보이지만 sp:i++그 후에는 길을 잃습니다. 1은 var에 하나의 문자만 표시한다는 뜻이라는 것을 알고 있습니다 $sp.

나는 이것이 while결코 끝나지 않을 것이라는 것도 알고 있습니다.

내가 시도한 결과가 동일한 결과를 제공하지 않았기 때문에 몇 가지 차이점 echo이 있다는 점도 주목할 가치가 있습니다 .printfechoecho "\b${sp:i++%${#sp}:1}"인용하다

답변1

여기에는 두 가지 변수가 있습니다. 무슨 일이 일어나고 있는지 더 잘 볼 수 있습니다.

sp="abcd" i=0                                         # Initialisation
printf "%d %s %d\n" "$i" "${sp:i++%${#sp}:1}" "$i"    # Repeat this line a few times

보시다시피 표현식이 사용될 때 $i마다 1씩 증가합니다( ). $i++의 길이를 모듈로화하여 $sp문자열의 시작 인덱스로 사용합니다 $sp. 따라서 $iis 인 6경우 세 번째 문자가 인쇄 6 % 4됩니다 (문자열 오프셋은 0에서 시작).2$sp

다음과 같은 표현을 풀 수 있습니다.

sp="abcd" i=0
len_sp=${#sp}              # length of $sp

i=$(( i + 1 ))             # increment $i
mod_i=$(( i % len_sp ))    # wrap around length of $sp
sp_sub=${sp:mod_i:1}       # get substring of one character
printf "%s" "$sp_sub"      # print it

다른 흥미로운 부분은 echo -n ' '후행 개행 없이 공백을 인쇄하고 printf "\b"백스페이스 키를 인쇄한다는 것입니다.

답변2

echo는 전혀 똑똑한 일을 하지 않습니다. 단지 두 문자만 에코합니다.

  • \b백스페이스 키입니다. 이로 인해 화면에 하나의 열이 반환됩니다.

  • 보이는 문자는 변수 sp의 4개 문자 중 하나입니다. 그러면 화면에서 한 칸 앞으로 이동합니다. 그래서 끊임없이 캐릭터를 서로보다 우선시합니다. 그러니 / - \ |순서대로 시청하시면 됩니다.

내부에는 ${ .... }index 를 사용하여 4자를 반복하는 쉘 확장이 있습니다 i.

  • ${sp:i:1}의 내용에서 위치에 있는 문자를 선택하는 하위 문자열 확장을 사용하여 문자를 선택합니다 .i$sp

  • i++섹션은 i사용될 때마다 증가하여 에서 한 문자를 이동합니다 sp.

  • %의 끝까지 실행될 때 "처음으로 돌아가야" 하는 모듈로 연산입니다 .isp

  • ${#sp}길이를 반환하는 쉘 확장 입니다 sp.

이 트릭에서는 회전 속도를 늦추기 위해 루프 내 지연(예: 절전 0.25)이 필요합니다.

기다리고 있는 모든 작업이 완료되었는지 감지해야 합니다. 이 셸이 비동기 프로세스를 시작하면 "작업"을 실행하고 이제 하위 프로세스가 없는지 확인할 수 있습니다. 파일이 생성되기를 기다리고 있다면 이를 테스트할 수 있습니다.

관련 정보