이 쉘 스크립트는 왜 입력을 두 번 인쇄합니까?
스크립트가 5 이후의 입력을 무시할 것으로 예상했습니다.
스크립트:
#! /bin/bash
echo "Enter 5 words : "
read a b c d e
printf "> %s %s %s %s %s <" $a $b $c $d $e
산출:
user@linux:~$ pico ifs2.sh
user@linux:~$ ./ifs2.sh
Enter 5 words :
1 2 3 4 5
> 1 2 3 4 5 <user@linux:~$ ./ifs2.sh
Enter 5 words :
1 2 3 4 5 6
> 1 2 3 4 5 <> 6 <user@linux:~$ ./ifs2.sh
Enter 5 words :
1 2 3 4 5 6 7 8 9 0
> 1 2 3 4 5 <> 6 7 8 9 0 <user@linux:~$
또한 다음 스크립트는 $IFS 설정에 관계없이 작동합니다. 왜?
#! /bin/bash
old="$IFS"
IFS=":"
echo "IFS = $IFS"
echo "Enter 5 words : "
read a b c d e
printf "> %s %s %s %s %s <" $a $b $c $d $e
IFS="$old"
산출:
user@linux:~$ ./ifs2.sh
IFS = :
Enter 5 words :
1 2 3 4 5
> 1 2 3 4 5 <user@linux:~$ ./ifs2.sh
IFS = :
Enter 5 words :
1 2 3 4 5
> 1 2 3 4 5 <user@linux:~$ ./ifs2.sh
IFS = :
Enter 5 words :
1:2:3:4:5
> 1 2 3 4 5 <user@linux:~$
답변1
세 가지 질문이 있습니다.
- 그리고
read
, 변수 이름이 입력 필드보다 작으면 마지막 변수는 구분 기호를 사용하여 줄의 나머지 모든 필드에 바인딩됩니다. 이는 이것이 예상치 못한 첫 번째 예에$e
나타날 것임을 의미합니다.5 6
- 모두
$a
..$e
참조되지 않기 때문에 해당 값이 변경됩니다.필드 분할.$e
"5 6
"을 누르고 있으면 다음으로 확장됩니다.둘명령의 매개변수입니다. printf
%
대체하는 인수만큼 한 번에 많은 인수를 반복적으로 사용하여 모든 인수를 사용합니다 . 이것은문서 속에 묻힌처럼:format
피연산자는 매개변수 피연산자를 만족시키기 위해 필요한 만큼 여러 번 재사용되어야 합니다. 추가c
또는s
변환 지정자는 빈 문자열 인수가 제공된 것처럼 평가됩니다. 기타 추가 변환 사양은 0 인수가 제공된 것처럼 평가됩니다.즉, 사용되지 않는 매개변수가 있는 경우 전체 형식 문자열을 포함하여 처음부터 다시 시작하여 처리합니다. 이는 전체 배열의 형식을 지정하려는 경우에 유용합니다. 예를 들면 다음과 같습니다.
printf '%b ' "${array[@]}"
귀하의
printf
명령은$a
각 ..에서 하나의 매개변수를 취하고 ..$d
에서 많은 매개변수가 남습니다$e
.$e
" " 이면 두 개의 루프가5 6
있고printf
두 번째에서는6
포맷이 시작됩니다. 그것이 나왔을 때5 6 7 8 9 10
두 번째 인쇄를 위해 완전히 교체되었습니다.
추가 가상 필드를 추가하고 매개변수 대체를 참조하면 read
이러한 모든 상황을 피할 수 있습니다(항상 좋은 생각입니다).
read a b c d e dummy
printf "> %s %s %s %s %s <" "$a" "$b" "$c" "$d" "$e"
그러면 다음이 제공됩니다.
Enter 5 words :
1 2 3 4 5 6 7 8 9 10
> 1 2 3 4 5 <
dummy
모든 추가 필드와 printf
예상되는 5개의 매개변수만 가져옵니다.
두 번째 편집 질문에도 비슷한 답변이 있습니다. a
공백이 없는 경우에만 값을 가져옵니다. 이는 .. 이 아무것도 확장되지 않음을 IFS
의미 하므로 인수는 하나만 얻을 수 있습니다. 형식 문자열에 공백을 대체하지 않고 인쇄합니다("빈 문자열 인수가 제공된 것처럼").$b
$e
printf
답변2
printf "> %s < " 1 2 3
인쇄할 것이다
> 1 <> 2 <> 3 <
printf "> %s %s <" 1 2 3
인쇄
> 1 2 <> 3 <
printf
형식 문자열을 충족하기 위해 모든 인수를 먹은 다음 모든 인수가 처리될 때까지 반복합니다.
두 번째 스크립트는 $a
명령이 다른 반복으로 유출되지 않도록에만 할당되었기 때문에 작동합니다(반복은 하나만 있음).
이 동작은 제공된 텍스트에 설명되어 있습니다 help printf
.
...모든 인수를 사용하기 위해 필요에 따라 형식이 재사용됩니다. 형식에 필요한 것보다 인수 수가 적은 경우 추가 형식 사양은 마치 적절한 0 값이나 빈 문자열이 제공된 것처럼 동작합니다. ...
에 의해 승인되었으며http://pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html