Shell-Script

echo 0x0A 時附加額外的 x0D

  • August 29, 2020

我正在嘗試將一些十六進制值發送到 tty 埠/dev/ttyS2。當我使用echo或者printf \x0A它會\x0D\x0A.

i=1 
a=$(printf "\xAA\xEE\x0A\x%02x" $i)
echo -ne   "$a"  > /dev/ttyS2

我在終端/串列埠上得到了這個——注意額外的 0D。我怎樣才能刪除它?

在此處輸入圖像描述

您需要禁用換行符轉換:

stty -F /dev/ttyS2 -onlcr

或者,對於嚴格的 POSIX stty

stty -onlcr < /dev/ttyS2

如果您希望字節按原樣通過串列連接雙向傳輸,您需要告訴系統它不被用作終端設備,方法是從中分離 tty 線路規則或發出:

stty raw -echo < /dev/ttyS2

在您的情況下,是onlcrtty 設備上預設啟用的屬性導致輸出時 LF 到 CRLF 轉換。您可以禁用所有輸出處理,包括ocrnlwith stty -opost,但這會保留所有輸入處理以用於在另一個方向傳輸的數據。

您沒有指出您正在使用哪個 shellechoprintf實現,但請注意-n,-e選項不是標準的,並且未指定參數包含的行為printf或何時包含。echo``\x

printf其格式參數的幾個實現擴展\xHH為值 0xHH 的字節。

在那些

printf "\xAA\xEE\x0A\x%02x" $i

將擴展\xAA為字節 0xAA 並且 for\x將其擴展為字節 0 或按\x字面意思擴展或抱怨缺少十六進制數字。所以你最終會得到<0xaa><0xee><LF>\x01in$a例如。

一些echo實現也解釋\xHH序列(一些僅在傳遞-e選項時)。

在這裡,如果你想便攜,你會這樣做:

a=$(printf '\\252\\356\\012\\%03o' "$i")
printf "$a" > /dev/ttyS2

或者:

a=$(printf '\\0252\\0356\\0012\\0%03o' "$i")
printf %b "$a" > /dev/ttyS2

(標準printf支持\ooo格式中的八進制序列,以及一種%b旨在模擬某些echo實現使用或不使用的擴展類型-e,並且八進制序列表示為的格式\0ooo)。

您還想確保第一個printf不輸出 NUL 字節,除了 之外zsh,shell 不能在其變數中儲存 NUL 字節(a=$(printf '\0 or \x00 or \u0000')例如,不要這樣做)。

zsh

bytes=(0xaa 0xee 0x0a $i)
set +o multibyte
printf %s ${(#)bytes} > /dev/ttyS2

該數據可以儲存在一個變數中:

printf -v data %s ${(#)bytes}

或者

data=${(#j[])bytes}

但更一般地說,如果您想處理具有任意字節值的數據,您可能需要使用適當的程式語言,即使它是一種解釋語言,例如perlor python

另一種方法是使用xxd可以在二進制形式和文本十六進制轉儲之間來迴轉換的工具。

printf aaee0a%02d "$i" | xxd -p -r > /dev/ttyS1

引用自:https://unix.stackexchange.com/questions/606029