为什么我的字母表有 40 个字母?或者为什么放弃 STDERR 并不总是一个好主意? [已关闭]

问题描述 投票:0回答:3

for ((i=000;i<040;i++));do ...

从0到39,有40个值!? ...用于从

A
打印到
Z
???

for ((i=000;i<040;i++));do
    echo -e $(eval "printf "\\\\%04o" $((65+0$i)) ");
  done 2>/dev/null |
  xargs
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

奇怪!?

85 值,从 70 到 154:

for ((i=0070;i<0155;i++));do
    echo -e $(eval "printf "\\\\%04o" $((19+0$i)) ");
  done 2>/dev/null |
    xargs
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

😜 虚拟请求(关于错误处理)!不要再打开这个!! ;-p

回答

由于这个问题已关闭,无法添加答案,所以有的解释:

误解是由于(ab)使用
2>/dev/null
!!

因此,只需删除它就会输出:

for ((i=000;i<040;i++));do
    echo -e $(eval "printf "\\\\%04o" $((65+0$i)) ")
done  |   xargs
bash: 65+08: value too great for base (error token is "08")
bash: 65+09: value too great for base (error token is "09")
bash: 65+018: value too great for base (error token is "018")
bash: 65+019: value too great for base (error token is "019")
bash: 65+028: value too great for base (error token is "028")
bash: 65+029: value too great for base (error token is "029")
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

事情变得更加清晰!!

我们可以使用 wc -l:

 来计算 
错误行

for ((i=000;i<040;i++));do
    echo -e $(eval "printf "\\\\%04o" $((65+0$i)) ")
done 2> >(wc -l >&2) |   xargs
6
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

有 6 个错误行,因为八进制数字中的非法数字

8
9

所以如果这是八进制,那么你可以

printf %d\\n 040

echo $(( 040 ))

echo $(( 8#40 ))

040
八进制转换为
32
十进制 (
4 * 8 + 0 = 32
)。

然后进行

32
操作并删除
6
错误,最终有 26 个输出。

再次与

wc -l

for ((i=0070;i<0155;i++));do
    echo -e $(eval "printf "\\\\%04o" $((19+0$i)) ")
  done 2> >(wc -l >&2) | xargs 
27
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

实际上有 27 个错误,其值来自...

printf "%d\n" 0070 0155
56
109

从56到108!不是 85 个值,而是 53 个!!

echo $(( 155 - 70 ))  $(( 0155 - 070 ))  $(( 109 - 56 ))
85 53 53

再次强调:53 次操作有 27 个错误 = 26 个输出

echo $((53-27))
26

是的!

这是正确的字母数(在我知道的字母表中)!

结论

问题可以重写为:

滥用
/dev/null
如何会做出奇怪的行为

所以重定向时要小心

STDERR
!避免简单地将
STDERR
重定向到
/dev/null
:

command 2>/dev/null

并且更喜欢使用以下命令:

command 2> >(grep -v "unwanted message" >&2)
bash error-handling
3个回答
6
投票

您只需使用八进制数字,因为您的数字以 0 为前缀。

所以它是基数 8,而不是基数 10。


6
投票

您有 31 个步骤,因为 040 是八进制,代表十进制 32。

八进制是以 8 为基数的数字系统。十进制以 10 为基数,十六进制以 16 为基数。


1
投票

为什么不直接使用下面的方法来打印字母表呢?

for letter in {A..Z} ; do
    echo $letter
done  
© www.soinside.com 2019 - 2024. All rights reserved.