저는 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
이 있다는 점도 주목할 가치가 있습니다 .printf
echo
echo "\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
. 따라서 $i
is 인 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
.%
의 끝까지 실행될 때 "처음으로 돌아가야" 하는 모듈로 연산입니다 .i
sp
${#sp}
길이를 반환하는 쉘 확장 입니다sp
.
이 트릭에서는 회전 속도를 늦추기 위해 루프 내 지연(예: 절전 0.25)이 필요합니다.
기다리고 있는 모든 작업이 완료되었는지 감지해야 합니다. 이 셸이 비동기 프로세스를 시작하면 "작업"을 실행하고 이제 하위 프로세스가 없는지 확인할 수 있습니다. 파일이 생성되기를 기다리고 있다면 이를 테스트할 수 있습니다.