此命令将0xff在 Linux 中填充文件。
dd if=/dev/zero ibs=1k count=100 | tr "\000" "\377" >paddedFile.bin
Run Code Online (Sandbox Code Playgroud)
当我在 OSX 中运行它时,结果是不同的。
$ dd if=/dev/zero ibs=1k count=100 | tr "\000" "\377" >paddedFile.bin
100+0 records in
200+0 records out
102400 bytes transferred in 0.000781 secs (131104008 bytes/sec)
$ hexdump -C paddedFile.bin
00000000 c3 bf c3 bf c3 bf c3 bf c3 bf c3 bf c3 bf c3 bf
|................|
*
00032000
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?
Gia*_*968 10
这一切都取决于运行时在终端会话中设置的LANGorLC_ALL值tr。Linux 将它们设置为,C而 macOS 将其设置为类似en_US.UTF-8. 当然,这en_US可能是其他一些本地语言,例如en_UK(英国英语),但关键是[something].UTF-8设置而不是纯 ASCII viaC是导致这种情况的原因。
似乎tr在 macOS 中将 转换0xff为 UTF8 等价物,c3bf而不是纯 ASCII 0xff。在此 Apple 社区支持线程中对此进行了解释:
Linux 不像 Mac 那样在终端中处理 Unicode。如果将“LANG”环境变量设置为“C”(在 Linux 上可能是这样),它将起作用。否则,所有这些高位都将被解释为 Unicode 字符。
使用该LANG提示有效!只需执行以下操作;我刚刚在 macOS 10.13.6 (High Sierra) 上亲自测试过。
首先,记下现有的LANG值是这样的:
echo $LANG
Run Code Online (Sandbox Code Playgroud)
我看到的输出是:
en_US.UTF-8
Run Code Online (Sandbox Code Playgroud)
现在将LANG值设置为C这样:
LANG=C
Run Code Online (Sandbox Code Playgroud)
并再次运行该命令:
dd if=/dev/zero ibs=1k count=100 | tr "\000" "\377" >paddedFile.bin
Run Code Online (Sandbox Code Playgroud)
现在这些hexdump值应该是这样的:
hexdump -C paddedFile.bin
00000000 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00019000
Run Code Online (Sandbox Code Playgroud)
要重置该LANG值,只需关闭该终端会话或运行以下命令:
LANG=en_US.UTF-8
Run Code Online (Sandbox Code Playgroud)
或者——正如评论中所指出的——你可以LANG在tr像这样调用之前直接在命令行选项中设置值:
dd if=/dev/zero ibs=1k count=100 | LANG=C tr "\000" "\377" >paddedFile.bin
Run Code Online (Sandbox Code Playgroud)
你甚至可以使用LC_ALL而不是LANG因为LANG它只是从LC_ALL这样派生出来的:
dd if=/dev/zero ibs=1k count=100 | LC_ALL=C tr "\000" "\377" >paddedFile.bin
Run Code Online (Sandbox Code Playgroud)
问题是trLinux 上的GNU并没有真正的多字节字符的概念,而是一次一个字节地工作。
该tr手册页的字符和在线文档的说话,但是这是一个有点简单化的。TODO源代码包中的文件提到了这一项(摘自coreutils 8.30):
使 wc、tr、fmt 等工具(大多数 textutils)适应多字节感知。问题是我想避免复制重要的逻辑块,但我也想在单字节模式下运行时只产生最小(最好是“无”)成本。
在 Linux 系统上——即使使用 UTF-8 语言环境 ( en_US.UTF-8)——GNUtr将 an 替换ä为两个“字符”( 的 UTF-8 表示ä有两个字节):
linux$ echo 'ä' | tr 'ä' 'x'
xx
Run Code Online (Sandbox Code Playgroud)
同样,混合 anä和 anö会产生有趣的结果,因为它们的 UTF-8 表示共享一个公共字节:
linux$ echo 'ö' | tr ä x
x?
Run Code Online (Sandbox Code Playgroud)
或者反过来(x这里不适用):
linux$ echo ab | tr ab äx
ä
Run Code Online (Sandbox Code Playgroud)
在您的情况下,GNUtr将 the\377作为原始字节值。
在trMac上是不同的,它知道的多字节字符的概念,并采取相应的行动:
mac$ echo 'ä' | tr ä x
x
mac$ echo ab | tr ab äx
äx
Run Code Online (Sandbox Code Playgroud)
数值为 0377 (U+00ff) 的字符的 UTF-8 表示是两个字节c3 bf,所以这就是你得到的。
tr逐字节工作的简单方法是使用 C 语言环境,而不是 UTF-8 语言环境。这再次给出了有趣的行为:
$ echo 'ä' | LC_ALL=C tr 'ä' 'x'
xx
Run Code Online (Sandbox Code Playgroud)
在您的情况下,您可以使用:
... | LC_ALL=C tr "\000" "\377"
Run Code Online (Sandbox Code Playgroud)
或者你可以使用类似 Perl 的东西来生成这些\xff字节:
perl -e 'printf "\377" x 1000 for 1..100'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1537 次 |
| 最近记录: |