[Comm] Запись CD/DVD

=?iso-8859-1?q?iceb_=CE=C1_svitonline=2Ecom?= =?iso-8859-1?q?iceb_=CE=C1_svitonline=2Ecom?=
Пн Ноя 3 09:39:45 MSK 2003


В Пон, 3 Ноя 2003, DM написал(а):

D> Здравствуйте, Aleksey Korotkov!
D>
D> Понедельник 03 Ноябрь 2003 01:09, Вы писали:
D>
D> > Оно там есть изначально :) Примерно так:
D> >
D> > mkisofs -r -J ~/my_data | cdrecord -v dev=0,0,0 speed=20 -
D>
D> Угу... Ясно. А на практике это дело когда-нибудь проверялось?
D> В смысле
D> возможности исчерпания буфера при записи из-за несинхронной
D> работы
D> mkisofs  и cdrecord?  Скажем, когда cdrecord стоит и ждёт, а
D> mkisofs в
D> это время что-то делает внутри себя и в stdout ничего не
D> отсылает? Или
D> такого в принципе не может быть?
D>

Теоретически - может. Бороться можно двумя путями: увеличением
объема fifo-буфера и поднятием приоритета задачи. Второй способ
доступен только при запуске от рута (что, впрочем, часто
необходимо и по другим причинам). Пример скрипта, который это
делает - в аттаче.

-- 
Yura Kalinichenko
----------- следующая часть -----------
#!/bin/sh
# $Id$
#
# bcd - Backup on CD 

# My NEC 7800B: 16x10x40

# ПЕРЕМЕННЫЕ ПАРАМЕТРЫ:
# 1. SCSI ID устройства. Можно получить по команде:
#    cdrecord -scanbus
devid=0,0,0

# 2. Файл устройства
devname=/dev/cdrom

# 3. Точка монтирования устройства, прописанная в /etc/fstab
mountpoint=/mnt/cdrom

# 4. Потолок скорости записи дисков R и RW
Rspeed=16
RWspeed=10

# 5. Метод очистки CD-RW
blank=fast

# 6. Объём FIFO-буфера. Чем больше, тем меньше вероятность прерывания 
#    при записи
fifo=8m

# 7. Корневая директория на CD, в которую будет запись. Строится
#    из текущей даты и времени - чтобы избежать идентичности
#    путей при дописывании.
rootdir=`date +%d%m%y-%H.%M`

#-------------------
tf=/tmp/cdwrite.$$
status=1
paths=""

#
# РАЗБОР КОМАНДНОЙ СТРОКИ
#
if [ $# -lt 1 ]; then
   echo "Usage:"
   echo
   echo "$0 [-v] dir1 dir2 ... dirn"
   exit 1
fi

CMD=`getopt -o v -- "$@"`
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
eval set -- "$CMD"
while true ; do
   case "$1" in
   -v) verify=on
       shift 
       ;;
   --) shift ; break 
       ;;
   esac
done

doptions="--no-shadow --backtitle \"Запись на компакт-диск\""
for dn in $* ; do
  if [ -d $dn ]; then
     paths="$paths $rootdir/$dn=$dn"
  else
     eval dialog $doptions --title \"Предупреждение\" \
--msgbox \"$dn не директория и потому записан не будет.\" 7 30
  fi
done

#
# ЗАПИСЬ
#
while eval dialog $doptions --msgbox \"Установите компакт-диск в дисковод \
и нажмите Enter.\" 7 33 ; do
   cmd="fs=$fifo dev=$devid"
   rw=`cdrecord -atip dev=$devid 2>/dev/null | grep "Is erasable"`
   msinfo=`cdrecord -msinfo dev=$devid 2>$tf`
   newcd=`grep "cdrecord: Cannot read session offset" $tf`
   if [ -z "$rw" ]; then
      # диск однократной записи
      speed=$Rspeed
      if [ -z "$msinfo" ]; then
         if [ -n "$newcd" ]; then
            # еще нетронутая болванка
            eval dialog $doptions --title Предупреждение \
            --yesno \"Диск не перезаписываемый. После выполнения записи на \
него потом можно будет только дописывать данные. Продолжать ?\"  7 50
            if [ $? -ne 0 ]; then
               eject $devname
               continue
            else
               blankmode="c"
            fi
         else
            # уже один раз записан и закрыт для дописывания
            eject $devname
            eval dialog $doptions --title Помилка \
            --msgbox \"Диск не перезаписываемый и дописывать на нього тоже нельзя.\"  7 50
            continue
         fi
      else
         # открыт для дописывания
         eval dialog $doptions --title Предупреждение \
         --yesno \"Диск не перезаписываемый. Дописывать в конец ?\"  7 50
         if [ $? -ne 0 ]; then
            eject $devname
            continue
         else
            blankmode="a"
         fi
      fi
    else
      # CD-RW 
      speed=$RWspeed
      if [ -z "$newcd" ]; then
         # уже что-то записывалось
         eval dialog $doptions --radiolist \"Диск перезаписываемый.\" \
           10 40 2 \
           c \"Стереть старые записи\" on \
           a \"Дописать\" off \
           2> $tf
         if [ $? -ne 0 ]; then 
            continue
         fi
         blankmode=`cat $tf`
      else 
         # первая запись
         blankmode="c"
      fi
      if [ "$blankmode" = "c" ]; then
         cmd="$cmd blank=$blank"
      fi
   fi
   clear
   isocmd="-R -D"
   if [ "$blankmode" = "a" ]; then
      isocmd="$isocmd -C $msinfo -M $devid"
   fi
   size=`mkisofs -print-size -quiet $isocmd -graft-points $paths 2>/dev/null`
   cmd="$cmd  speed=$speed -multi -tsize=${size}s"
#echo "mkisofs $isocmd -graft-points $paths"
#echo "cdrecord $cmd -v - "
#read aaa
   if [ $UID -eq 0 ]; then
      # работаем root'ом - поднимем приоритет (меньше вероятность прерывания)
      if nice --18 mkisofs $isocmd -graft-points $paths 2>/dev/null \
	   | cdrecord -overburn $cmd -v - 2>$tf ; then
           status=0
	   break
      else
        break
      fi
    else
      # обычный пользователь - работаем с обычным приоритетом
      if mkisofs $isocmd -graft-points $paths 2>/dev/null \
	   | cdrecord $cmd -v - 2>$tf ; then
           status=0
	   break
      else
        break
      fi
    fi
done

#
# ПРОВЕРКА
#
while [ $status -eq 0 -a "$verify" = "on" ]; do
     until eject $devname ; do
       sleep 1
     done
     status=1
     eval dialog $doptions --infobox \"Проверка записи, ждите...\" 7 30
     mount $mountpoint 2>$tf || break
     for dn in $* ; do
       if [ -d $dn ]; then
          diff -r $dn $mountpoint/$rootdir/$dn >/dev/null 2>$tf
          status=$?
	  if [ $status -ne 0 ]; then
	      echo "Неудачная проверка директории $dn" >> $tf
	      break
          fi
       fi
     done
     umount $mountpoint
     break
done

if [ $status -eq 0 ]; then
   eval dialog $doptions --title OK \
        --infobox \"Операция успешно завершена.\"  7 30
   sleep 1
   eject
else
   diag="Ошибка записи. Диагностика: `cat $tf`"
   eval dialog $doptions --title Ошибка \
     --msgbox \"$diag\"  10 60
fi
rm -f $tf
exit $status


Подробная информация о списке рассылки community