Linux 스크립트 - 읽기/설치 전에 CD/DVD 미디어가 로드될 때까지 기다리는 방법은 무엇입니까?

Linux 스크립트 - 읽기/설치 전에 CD/DVD 미디어가 로드될 때까지 기다리는 방법은 무엇입니까?

저는 NAS에서 100개의 CD/DVD를 읽기 위한 빠르고 간단한 스크립트를 작성하고 있습니다. 트레이 꺼내기 및 로드를 처리하지만 미디어를 트레이에 삽입한 후 OS에서 미디어를 사용할 수 없도록 기다리거나 방지하는 쉬운 방법을 찾지 못했습니다.

  • eject -t트레이를 닫은 후 즉시 종료
  • mount실패할 것이다미디어를 찾을 수 없습니다직후에 실행되는 경우 eject15초 후에 실행될 수도 있습니다.

디스크는 꽤 오래되었고 일부는 사용할 수 있게 되기까지 시간이 꽤 걸리므로 "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_disctray_opendrive_not_readydisc_ok

두 개의 매개변수를 사용하여 호출하는 경우:

cdstatus /dev/sr1 1.3

/dev/sr1상태가 될 때까지 1.3초마다 폴링 합니다 disk_ok.

cc -Os -Wall cdstatus.c -s -o cdstatusgcc 및 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

관련 정보