为什么 printf 打印的参数比预期多?

为什么 printf 打印的参数比预期多?

为什么这个 shell 脚本打印输入两次?

我预计脚本会忽略 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

你有三个问题:

  1. read,如果变量名少于输入中的字段,则最后一个 var 将使用分隔符绑定到该行中的所有剩余字段。这意味着这$e会出现5 6在你的第一个意想不到的例子中。
  2. 因为所有$a..$e都没有被引用,所以它们的值会发生变化场分裂。如果$e持有“ 5 6”则它扩展为命令的参数。
  3. printf消耗其所有参数,一次使用与%替换一样多的参数,重复使用。这是埋藏在文档中作为:

    format应根据需要多次重用操作数以满足参数操作数。任何额外cs转换说明符都应像提供空字符串参数一样进行评估;其他额外的转换规范应像提供零参数一样进行评估。

    换句话说,如果有未使用的参数,它会重新开始并从头开始处理它们,包括整个格式字符串。当您想要格式化整个数组时,这非常有用,例如:

    printf '%b ' "${array[@]}"
    

    您的printf命令从每个$a..获取一个参数$d,然后从 .. 中剩下许多参数$e。当$e是“ ”时5 6printf有两次循环,第二次刚刚开始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仅获取您期望的五个参数。


您的第二个编辑问题有类似的答案:仅在没有空格a时才获取值。IFS这意味着$b..$e扩展到什么都没有,所以printf只得到一个参数。打印格式字符串中的空格,它们之间没有任何替换(“就像提供了空字符串参数一样”)。

答案2

 printf "> %s < " 1 2 3

将打印

 > 1 <> 2 <> 3 <

  printf "> %s %s <" 1 2 3

印刷

 > 1 2 <> 3  <

printf吃掉所有参数以满足其格式字符串,然后重复直到处理完所有参数。

第二个脚本之所以有效,是因为 only$a曾被分配给,因此该命令不会溢出到其他迭代中(只有一次迭代)。


此行为记录在提供的文本中help printf

...该格式根据需要重新使用以消耗所有参数。如果参数少于格式所需的数量,则额外的格式规范的行为就像已提供适当的零值或空字符串一样。 ...

并由以下机构授权http://pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html

相关内容