正确转义 echo -ne

正确转义 echo -ne

我正在将 echo -ne 命令输出到 USB 鼠标 HID 设置脚本中的文件。

以下是在启动时通过 /etc/rc.local 以 root 身份运行的脚本:

#accidentally had a newline here <---  
#!/bin/bash
cd /sys/kernel/config/usb_gadget/
mkdir -p isticktoit
cd isticktoit
echo 0x1d6b > idVendor # Linux Foundation
echo 0x0104 > idProduct # Multifunction Composite Gadget
echo 0x0100 > bcdDevice # v1.0.0
echo 0x0200 > bcdUSB # USB2
mkdir -p strings/0x409
echo "fedcba9876543210" > strings/0x409/serialnumber
echo "JW" > strings/0x409/manufacturer
echo "DoItForTheWenHua" > strings/0x409/product
mkdir -p configs/c.1/strings/0x409
echo "Config 1" > configs/c.1/strings/0x409/configuration
echo 0x80 > configs/c.1/bmAttributes
echo 250 > configs/c.1/MaxPower
# Add functions here
mkdir -p functions/hid.usb0
echo 1 > functions/hid.usb0/protocol
echo 1 > functions/hid.usb0/subclass
echo 3 > functions/hid.usb0/report_length
# NEXT LINE CAUSES ISSUES 
echo -ne \\x05\\x01\\x09\\x02\\xa1\\x01\\x09\\x01\\xa1\\x00\\x05\\x09\\x19\\x01\\x29\\x03\\x15\\x00\\x25\\x01\\x95\02\\x81\\x06\\xc0\\xc0 > functions/hid.usb0/report_desc
ln -s functions/hid.usb0 configs/c.1/
# End functions
ls /sys/class/udc > UDC

echo -ne 的预期结果是写入文件函数/hid.usb0/report_desc 的字符序列,以 0x05、0x01、0x09 等开头。相反,我得到了

$ cat /sys/kernel/config/usb_gadget/isticktoit/functions/hid.usb0/report_desc
-ne \x05\x01\x09\x02\xa1\x01\x09\x01\xa1\x00\x05\x09\x19\x01\x29\x03\x15\x00\x25\x01\x95\02\x81\x06\xc0\xc0

当我尝试测试这个时,我无法重现它。在 bash 中运行命令(有效):

pi@raspberrypi:~ $ echo -ne "\\x05\\x01\\x09\\x02\\xa1\\x01\\x09\\x01\\xa1\\x00\\x05\\x09\\x19\\x01\\x29\\x03\\x15\\x00\\x25\\x01\\x95\\x03\\x75\\x01\\x81\\x02\\x95\\x01\\x75\\x05\\x81\\x03\\x05\\x01\\x09\\x30\\x09\\x31\\x15\\x81\\x25\\x7f\\x75\\x08\\x95\\x02\\x81\\x06\\xc0\\xc0"
        ▒       ▒       )%▒u▒▒u▒        0       1▒▒▒▒▒

运行测试脚本(有效):

pi@raspberrypi:~ $ cat test
        ▒       ▒       )%▒u▒▒u▒        0       1▒▒▒▒▒
pi@raspberrypi:~ $ cat test.sh
#!/bin/bash

echo -ne "\\x05\\x01\\x09\\x02\\xa1\\x01\\x09\\x01\\xa1\\x00\\x05\\x09\\x19\\x01\\x29\\x03\\x15\\x00\\x25\\x01\\x95\\x03\\x75\\x01\\x81\\x02\\x95\\x01\\x75\\x05\\x81\\x03\\x05\\x01\\x09\\x30\\x09\\x31\\x15\\x81\\x25\\x7f\\x75\\x08\\x95\\x02\\x81\\x06\\xc0\\xc0" > test
pi@raspberrypi:~ $ ./test.sh
pi@raspberrypi:~ $ cat test
        ▒       ▒       )%▒u▒▒u▒        0       1▒▒▒▒▒P

Bash 重定向(有效):

pi@raspberrypi:~ $ echo -ne "\\x05\\x01\\x09\\x02\\xa1\\x01\\x09\\x01\\xa1\\x00\\x05\\x09\\x19\\x01\\x29\\x03\\x15\\x00\\x25\\x01\\x95\\x03\\x75\\x01\\x81\\x02\\x95\\x01\\x75\\x05\\x81\\x03\\x05\\x01\\x09\\x30\\x09\\x31\\x15\\x81\\x25\\x7f\\x75\\x08\\x95\\x02\\x81\\x06\\xc0\\xc0" > test
pi@raspberrypi:~ $ cat test
        ▒       ▒  )%▒u▒▒u▒        0       1▒▒▒▒▒

那么,我在这里做错了什么?

答:我没有把 shebang 放在正确的行上,它导致另一个 shell 解释我的脚本。

答案1

的行为echo是出了名的不可移植。当您的脚本不起作用时,它可能会与其他 shell 一起运行。 (你没有在运行sh scriptname,是吗?)看看echoBash 和 Dash 有何不同:

$ bash -c 'echo -ne \\x41\\x42\\x43\\x0a'
ABC

$ dash -c 'echo -ne \\x41\\x42\\x43\\x0a'
-ne \x41\x42\x43\x0a

通常,最好使用printf相反的方法,但仅此无济于事,因为并非所有printfs 都支持十六进制字符转义 ( \x00),仅支持八进制 ( \000),因此您也需要更改内容。无论如何,Bashprintf \\x41\\x42\\x43\\x0a会做与 Bash 相同的事情echo -en \\x41\\x42\\x43\\x0a,但稍微更便携。

您需要检查哪个 shell 运行该脚本。

也可以看看:为什么 printf 比 echo 更好?

相关内容