저는 NAS에서 100개의 CD/DVD를 읽기 위한 빠르고 간단한 스크립트를 작성하고 있습니다. 트레이 꺼내기 및 로드를 처리하지만 미디어를 트레이에 삽입한 후 OS에서 미디어를 사용할 수 없도록 기다리거나 방지하는 쉬운 방법을 찾지 못했습니다.
eject -t
트레이를 닫은 후 즉시 종료mount
실패할 것이다미디어를 찾을 수 없습니다직후에 실행되는 경우eject
15초 후에 실행될 수도 있습니다.
디스크는 꽤 오래되었고 일부는 사용할 수 있게 되기까지 시간이 꽤 걸리므로 "2분 동안 절전 모드"가 아닌 해결책은 피하고 싶습니다. 어떤 아이디어가 있나요? 우분투 18.04를 사용합니다.
답변1
괜찮나요?
while ! dd if=/dev/sr2 bs=2048 count=1 of=/dev/null 2>/dev/null; do sleep 1; done
/dev/sr2
실제 CD/DVD 장치로 교체하세요 .
No medium found
다음을 제외한 오류를 확인하여 더욱 강력하게 만들 수 있습니다. 손상된 DVD가 없기 때문에 테스트를 거치지 않았습니다.
dev=/dev/sr2
while :; do
err=$(dd if=$dev of=/dev/null bs=2048 status=none count=1 2>&1)
case $err in
"dd: failed to open '$dev': No medium found")
sleep 1 ;;
'')
# successfully opened
break ;;
*)
# unexpected error
# play some SOUND in the speakers
# and wait for user input to continue
read wtf ;;
esac
done
고쳐 쓰다:
이를 지원하는 드라이브에서 Linux는 장치를 열려고 할 때 트레이를 자동으로 닫습니다. 이 기능은 잠재적으로 비활성화될 수 있지만 ioctl(CDROM_CLEAR_OPTIONS, CDO_AUTO_CLOSE)
이를 구현하는 명령줄 유틸리티를 찾을 수 없습니다. 왜냐하면 그것은 사람들 C
이 모든 것을 더 잘 사용하도록 강요하기 때문입니다 C
.
여기 CD/DVD 드라이브 상태를 확인하고 폴링할 수 있는 작은 애플리케이션이 있습니다.
단일 인수로 호출하는 경우:
cdstatus /dev/sr1
, 또는 다음 상태 중 하나 가 인쇄됩니다 /dev/sr1
.no_disc
tray_open
drive_not_ready
disc_ok
두 개의 매개변수를 사용하여 호출하는 경우:
cdstatus /dev/sr1 1.3
/dev/sr1
상태가 될 때까지 1.3초마다 폴링 합니다 disk_ok
.
cc -Os -Wall cdstatus.c -s -o cdstatus
gcc 및 libc6-dev 패키지가 설치되어 있는 경우 .
cdstatus.c
#include <sys/ioctl.h>
#include <linux/cdrom.h>
#include <fcntl.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
int main(int argc, char **argv){
int fd, s; int pt = -1;
if(argc < 2)
errx(1, "usage: %s /dev/srX [poll_secs] [verbose]", argv[0]);
if((fd = open(argv[1], O_RDONLY|O_NONBLOCK)) == -1)
err(1, "open %s", argv[1]);
if(argc > 2 && ((pt = strtod(argv[2], 0) * 1000) < 1 || pt > 3600000))
errx(1, "bad timeout '%s'", argv[2]);
redo:
switch(s = ioctl(fd, CDROM_DRIVE_STATUS, 0)){
case -1: err(1, "ioctl(CDROM_DRIVE_STATUS)");
case CDS_NO_INFO: errx(1, "ioctl(CDROM_DRIVE_STATUS) not implemented");
}
if(pt < 0 || argc > 3)
switch(s){
case CDS_NO_DISC: printf("no_disc\n"); break;
case CDS_TRAY_OPEN: printf("tray_open\n"); break;
case CDS_DRIVE_NOT_READY: printf("drive_not_ready\n"); break;
case CDS_DISC_OK: printf("disc_ok\n"); break;
default: printf("status=%d\n", s); break;
}
if(pt > 0 && s != CDS_DISC_OK){
if(poll(0, 0, pt) < 0) err(1, "poll");
goto redo;
}
return s != CDS_DISC_OK;
}
답변2
마지막 하나이 모호하게 관련된 스레드에 게시하세요.wodim -atip
무엇보다도 Linux 문제에 권장되며 미디어를 사용할 수 있을 때까지 차단하는 데 효과적이라는 것이 입증되었습니다.
#!/bin/bash
set -e
DRIVE=${DRIVE:-"sr0"}
DESTROOT=${DESTROOT:-"/mnt/newshare"}
DRV_FULLNAME="$(</sys/class/block/$DRIVE/device/vendor) $(</sys/class/block/$DRIVE/device/model)"
[ -d /tmp/$DRIVE ] || mkdir /tmp/$DRIVE
while true; do
eject /dev/$DRIVE
echo "$DRV_FULLNAME is ready."
read -p "Enter next disc code: " DISC
if [ -z "$DISC" ]; then
echo "No disc code = we're done, exiting"
break
fi
eject -t /dev/$DRIVE || {
read -n1 -r -p "Unable to load tray. Push it in and hit Any key..."
echo
}
wodim dev=/dev/$DRIVE -atip > /dev/null || {
echo "Medium not detected."
break
}
mount /dev/$DRIVE /tmp/$DRIVE -o ro || {
echo "Couldn't mount medium."
break
}
cp -ia /tmp/$DRIVE/. $DESTROOT/$DISC/ || {
echo "COPY FAILED. Put it on the read-error pile and continue with next one."
}
done