echo -ne를 올바르게 이스케이프 처리하세요.

echo -ne를 올바르게 이스케이프 처리하세요.

echo -ne 명령 출력을 USB 마우스 HID 설정 스크립트의 파일로 파이프하고 있습니다.

다음은 시작 시 /etc/rc.local을 통해 루트로 실행되는 스크립트입니다.

#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의 예상 결과는 0x05, 0x01, 0x09 등으로 시작하여 파일 함수 /hid.usb0/report_desc에 기록된 일련의 문자입니다. 대신 나는 얻는다

$ 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을 올바른 줄에 넣지 않았고 이로 인해 다른 쉘이 내 스크립트를 해석하게 되었습니다.

답변1

이 동작은 echo이식성이 없는 것으로 악명이 높습니다. 스크립트가 작동하지 않으면 다른 셸에서 실행 중일 수 있습니다. (당신은 실행하고 있지 않습니까 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가 16진수 문자 이스케이프( \x00)를 지원하는 것은 아니고 8진수( \000)만 지원하므로 도움이 되지 않으므로 상황도 변경해야 합니다. 어쨌든 Bash는 printf \\x41\\x42\\x43\\x0aBash와 동일한 작업을 수행 echo -en \\x41\\x42\\x43\\x0a하지만 이식성이 약간 더 좋습니다.

어떤 쉘이 스크립트를 실행하고 있는지 확인해야 합니다.

또한보십시오:왜 printf가 echo보다 나은가요?

관련 정보