/etc/udev/rules.d/usbmount.rules에 다음 내용이 포함된 udev 규칙 파일이 있습니다.
ACTION=="add", KERNEL=="sd*[!0-9]", RUN+="/tmp/debug.sh"
규칙을 만든 후 다음을 수행했습니다.
chmod +x /tmp/debug.sh
udevadm control --reload-rules
이 규칙의 목적은 USB 블록 장치(썸 드라이브, 하드 드라이브 등)가 연결되어 있을 때 스크립트를 실행하는 것입니다. 왜 시동이 걸리지 않는지 알고 싶습니다. udevadmmonitor
USB 하드 드라이브 도크가 USB 3.0 포트를 통해 시스템에 연결되면 A는 다음 메시지를 표시합니다.
KERNEL[367.932459] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2 (usb)
KERNEL[367.934622] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0 (usb)
KERNEL[367.935236] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0 (scsi)
KERNEL[367.935301] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/scsi_host/host0 (scsi_host)
KERNEL[367.935414] bind /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0 (usb)
KERNEL[367.935527] bind /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2 (usb)
UDEV [367.937750] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2 (usb)
UDEV [367.939195] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0 (usb)
UDEV [367.939940] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0 (scsi)
UDEV [367.945817] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/scsi_host/host0 (scsi_host)
UDEV [367.947464] bind /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0 (usb)
UDEV [367.950394] bind /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2 (usb)
KERNEL[368.957786] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0 (scsi)
KERNEL[368.957902] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0 (scsi)
KERNEL[368.957993] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/scsi_device/0:0:0:0 (scsi_device)
KERNEL[368.958128] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/scsi_generic/sg0 (scsi_generic)
KERNEL[368.958250] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/bsg/0:0:0:0 (bsg)
KERNEL[368.960906] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0 (scsi_disk)
UDEV [368.961035] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0 (scsi)
UDEV [368.965594] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0 (scsi)
UDEV [368.971313] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/scsi_device/0:0:0:0 (scsi_device)
UDEV [368.973129] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/bsg/0:0:0:0 (bsg)
UDEV [368.975431] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/scsi_generic/sg0 (scsi_generic)
UDEV [368.976153] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0 (scsi_disk)
KERNEL[369.010196] add /devices/virtual/bdi/8:0 (bdi)
UDEV [369.011230] add /devices/virtual/bdi/8:0 (bdi)
KERNEL[369.270352] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/block/sda (block)
KERNEL[369.270455] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/block/sda/sda1 (block)
KERNEL[369.276694] bind /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0 (scsi)
UDEV [369.874116] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/block/sda (block)
UDEV [370.252695] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/block/sda/sda1 (block)
UDEV [370.275646] bind /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0 (scsi)
기계 정보:
OS: Raspbian GNU/Linux 10 (buster)
Kernel: 5.4.72-v7l+
debug.sh의 유일한 내용은 echo "TESTING" >> /tmp/debuglog.txt
. Debuglog.txt가 생성되지 않았습니다.
이 규칙이 실행되지 않는 것 같습니다. 왜? 이 문제를 해결하려면 어떻게 해야 합니까?
답변1
이것debug.sh의 유일한 콘텐츠예
echo "TESTING" >> /tmp/debuglog.txt
. Debuglog.txt가 생성되지 않았습니다.
여기에 문제가 있습니다. #!/bin/bash
커널은 실행을 위임하도록 강제하지 않기 때문에 이러한 쉘 스크립트를 실행하지 않습니다.세게 때리다통역사.
대부분의 도구는 즉시 실행되지 않는 경우 명령을 실행하기 위해 셸을 사용하기 때문에 이런 일이 거의 발생하지 않습니다. 이는 다음과 같은 경우의 예입니다.길perl을 사용하여 이 명령을 실행합니다(또한 스크립트 실행을 즉시 실패하게 만드는 도구를 성공하지 못한 채 검색함).
$ strace -e execve perl -e 'exec ("/tmp/debug.sh");'
execve("/usr/bin/perl", ["perl", "-e", "exec (\"/tmp/debug.sh\");"], [/* 15 vars */]) = 0
execve("/tmp/debug.sh", ["/tmp/debug.sh"], [/* 15 vars */]) = -1 ENOEXEC (Exec format error)
execve("/bin/sh", ["/bin/sh", "/tmp/debug.sh"], [/* 15 vars */]) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=14452, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
+++ exited with 0 +++
먼저 첫 번째 줄에서 인터프리터 없이 스크립트를 실행하려고 시도하고 다음을 얻습니다.
ENOEXEC (Exec format error)
그런 다음 케이스를 다시 삽입해 보세요. 여기서는 이 환경에도 /bin/sh
없기 bash
때문에 스크립트에 bash
구문이 포함되어 있으면 나중에 미묘하게 잘못 동작하게 됩니다.
원래는 /tmp/debug.sh
다음과 같았습니다( u+rx
파마 포함).
#!/bin/bash
echo "TESTING" >> /tmp/debuglog.txt
그 다음에:
$ strace -e execve perl -e 'exec ("/tmp/debug.sh");'
execve("/usr/bin/perl", ["perl", "-e", "exec (\"/tmp/debug.sh\");"], [/* 15 vars */]) = 0
execve("/tmp/debug.sh", ["/tmp/debug.sh"], [/* 15 vars */]) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=14474, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
+++ exited with 0 +++
그런 다음 /tmp/debug.sh
커널에 의해 직접 실행됩니다(효과적으로 실행을 연기함 /bin/bash
).
udev
이 작업을 시도하지 않으므로 유효한 바이너리가 필요합니다.커널용명령의 첫 번째 파일로. 직접 제공하거나 해당 줄부터 시작하여 커널 관점에서 충분히 실행 가능한 스크립트를 제공하십시오 #!/path/to/interpreter
.
답변2
일부 시스템(모두?)의 udev에는 모든 스크립트를 실행하기 위한 절대 경로가 필요합니다. 쉘 스크립트를 실행하려면 쉘을 지정해야 합니다. 그것이 작동하려면 다음과 같이 변경해야했습니다.
ACTION=="add", KERNEL=="sd*[!0-9]", RUN+="/bin/bash /tmp/debug.sh"