Где-то зарылась ошибка в цикле. Помогите найти (Цикл результативно отрабатывает один раз из 100)

На самом деле это единственный раздел про unix на этом форуме

Модераторы: /dev/random, Модераторы разделов

Аватара пользователя
alkesta
Сообщения: 345
ОС: Fedora

Где-то зарылась ошибка в цикле. Помогите найти

Сообщение alkesta »

Задача: порезать файл m4b на главы и сохранить каждую главу в отдельном файле m4a. Все описано в этой теме: AudioBook.M4B -> 001.M4A, 002.M4A ...

Создается только первая глава (офин файл). Что-то никак не могу понять в чем косяк....

Код: Выделить всё

$ cat m4b_to_m4as.sh
#!/bin/sh

TRACK=0
READY=false
INPUTFILE="$1"

ARTIST=`cat chapter.list | awk '/artist:/' | sed '/album_artist:/d' | sed 's/artist: //'`
ALBUM_ARTIST=`cat chapter.list | awk '/album_artist:/' | sed 's/album_artist: //'`
ALBUM=`cat chapter.list | awk '/album:/' | sed '/album_artist:/d' | sed 's/album: //'`
GENRE=`cat chapter.list | awk '/genre:/' | sed 's/genre: //'`
YEAR_DATE=`cat chapter.list | awk '/date:/' | sed 's/date: //'`

mkdir "$ALBUM"


 while read LINE; do
  if [[ "$LINE" == *title* ]]; then
      TRACK=$(( $TRACK + 1))
      READY=true
      TITLE=`echo $LINE | awk '/title:/' |  sed 's/title: //'`
  else
      READY=false
  fi

  if [[ "$LINE" == *Chapter* ]]; then
      START_TXT=`echo $LINE | awk '/Chapter/ {print $4}' | sed 's/,*$//'`
      START_POS=$(echo "scale=3; $START_TXT" | bc)
      END_POS=`echo $LINE | awk '/Chapter/ {print $6}'`
      DURATION=`echo "$END_POS $START_POS" | awk '{print $1 - $2}'`
  fi

  if [[ "$READY" == true ]]; then
      ffmpeg -i "$INPUTFILE" -ss "$START_POS" -t "$DURATION" -sn -acodec copy \
      -metadata title="$TITLE" -metadata artist="$ARTIST" -metadata album="$ALBUM" \
      -metadata date="$YEAR_DATE" -metadata genre="$GENRE" -metadata track="$TRACK" "./$ALBUM/$TRACK.m4a"
  fi

done < chapter.list


Спасибо сказали:
Аватара пользователя
seisros
Сообщения: 78
ОС: Calculate 13.04

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение seisros »

alkesta писал(а):
29.05.2013 21:24
Создается только первая глава (офин файл). Что-то никак не могу понять в чем косяк....


Ясное дело он будет один, это bash язык, а не C++. Я не заметил тут цикла повтора. Только циклы условий.
Многие говорят что трудно жить по высшему закону. А спать трудно? А пробуждаться?
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4823
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение SLEDopit »

seisros писал(а):
29.05.2013 22:10
Я не заметил тут цикла повтора. Только циклы условий.
Есть там цикл. Смотрите строку с while. Подробности в man bash.

alkesta,
не стоит дублировать топики. (:

ну теперь по существу:
скрипт рабочий. по крайней мере в bash всё отлично. однако у вас в шебанге стоит #!/bin/sh , который далеко не всегда является bash'ем. попробуйте заменить на явный /bin/bash.
Ну и ошибки какие-нибудь есть? Может вы нам выхлоп скрипта покажете?
Ещё можно в начале скрипта поставить set -x и посмотреть что там вообще происходит. Часто этого достаточно, чтобы найти что не так.

зы. пара хинтов:

Код: Выделить всё

awk '/title:/' |  sed 's/title: //' == sed -n '/title/s/title: //p'
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
seisros
Сообщения: 78
ОС: Calculate 13.04

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение seisros »

SLEDopit писал(а):
29.05.2013 22:25
seisros писал(а):
29.05.2013 22:10
Я не заметил тут цикла повтора. Только циклы условий.
Есть там цикл. Смотрите строку с while. Подробности в man bash.


Теперь вижу, ну только извращенцы могут так писать. Конкатенация же не много проще и экономнее, плюс сразу в глаза бросается.
Многие говорят что трудно жить по высшему закону. А спать трудно? А пробуждаться?
Спасибо сказали:
Аватара пользователя
alkesta
Сообщения: 345
ОС: Fedora

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение alkesta »

Контрольными echo установил, что это ffmpeg прерывает работу цикла. На сколько я понял это связано с STDIN/STDOUT/STDERR. Начал гуглить...

Методом тыка скрипт заработал с использованием в конце строки </dev/null & взял отсюда:

Код: Выделить всё

--------cut-----------------
ffmpeg -i "$INPUTFILE" -ss "$START_POS" -t "$DURATION" -sn -acodec copy \
      -metadata title="$TITLE" -metadata artist="$ARTIST" -metadata album="$ALBUM" \
      -metadata date="$YEAR_DATE" -metadata genre="$GENRE" -metadata track="$TRACK" "./$ALBUM/$TRACK.m4a" </dev/null &

--------cut------------------


все работает, но ffmpeg откодировав все не завершает работу ( нужно жать CTRL+C). Что это за зверь - </dev/null & ?

UPD: Что-то теперь какие-то проблемы в ситеме после </dev/null & ;)

Код: Выделить всё

$ mc
Cannot get terminal settings: Inappropriate ioctl for device (25)


UPD2
seisros писал(а):
29.05.2013 22:38
Теперь вижу, ну только извращенцы могут так писать. Конкатенация же не много проще и экономнее, плюс сразу в глаза бросается.

Я не извращенец ;) Это фактически мой первый рабочий скрипт, который написан с нуля за 2 дня, до этого вообще со скриптами дела не имел.
Что есть "Конкатенация"? Можно на примере?
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4823
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение SLEDopit »

seisros писал(а):
29.05.2013 22:38
Теперь вижу, ну только извращенцы могут так писать.
Это вполне рабочий нормальный метод.
seisros писал(а):
29.05.2013 22:38
Конкатенация же не много проще и экономнее, плюс сразу в глаза бросается.
Что есть "конкатенация" в данном контексте, которая ещё и экономнее?

alkesta писал(а):
29.05.2013 22:47
</dev/null &
это штука говорит ffmpeg'у, чтобы он не ожидал ввода с клавиатуры и запустился в фоне. зачем это вам нужно, мне неизвестно.
сам ffmpeg нормально отрабатывает? ошибок не выплёвывает? exit статус не проверяли?
хотя скрипт написан так, что даже ошибка в цикле не должна прерывать его.
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
seisros
Сообщения: 78
ОС: Calculate 13.04

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение seisros »

alkesta писал(а):
29.05.2013 22:47
Что это за зверь - </dev/null & ?


/dev/null это "не что". Пустое устройство, файл да и вообще что угодно. Это не ноль как многие считают это именно "не что". Кстати светую посмотреть ужастик снятый в прошлом году под назнанием "нечто".
Многие говорят что трудно жить по высшему закону. А спать трудно? А пробуждаться?
Спасибо сказали:
Аватара пользователя
alkesta
Сообщения: 345
ОС: Fedora

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение alkesta »

Сам ffmpeg отрабытывает нормально, все время им пользуюсь. Проблема появилась именно при работе в скрипте. И только с </dev/null & заработало.


seisros писал(а):
29.05.2013 23:20
alkesta писал(а):
29.05.2013 22:47
Что это за зверь - </dev/null & ?


/dev/null это "не что". Пустое устройство, файл да и вообще что угодно. Это не ноль как многие считают это именно "не что". Кстати светую посмотреть ужастик снятый в прошлом году под назнанием "нечто".


Когда что-то в /dev/null (> /dev/null ) - это понятно.
А тут <
Спасибо сказали:
Аватара пользователя
seisros
Сообщения: 78
ОС: Calculate 13.04

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение seisros »

alkesta писал(а):
29.05.2013 23:28
Когда что-то в /dev/null (> /dev/null )- это понятно.
А тут <


Это "<" значит вывести куда либо, в переменную или монитор. ">" значит ввести или записать. Обычный синтаксис C++ с подключённой библиотекой (IO ввода вывода). Попробуйте C++ в linux с компилятором gcc. всё просто и лекго.
Многие говорят что трудно жить по высшему закону. А спать трудно? А пробуждаться?
Спасибо сказали:
Аватара пользователя
alkesta
Сообщения: 345
ОС: Fedora

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение alkesta »

seisros писал(а):
29.05.2013 23:34
alkesta писал(а):
29.05.2013 23:28
Когда что-то в /dev/null (> /dev/null )- это понятно.
А тут <

Это "<" значит вывести куда либо, в переменную или монитор.


Что-то я не понимаю, вывести из ничего в ffmpeg пустоту!?

Если говорит ffmpeg'у, чтобы он не ожидал ввода с клавиатуры, так он наоборот стал незавершать работу.. надо жать Ctrl+C.
Спасибо сказали:
Аватара пользователя
sgfault
Сообщения: 586
Статус: -

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение sgfault »

alkesta писал(а):
29.05.2013 23:41
seisros писал(а):
29.05.2013 23:34

Это "<" значит вывести куда либо, в переменную или монитор.


Что-то я не понимаю, вывести из ничего в ffmpeg пустоту!?

Если говорит ffmpeg'у, чтобы он не ожидал ввода с клавиатуры, так он наоборот стал незавершать работу.. надо жать Ctrl+C.

seisros написал ерунду. 'n<file' значит открыть на чтение файл file на дескрипторе n. Если дескриптор не указан, то это 0 (те стандартный ввод).
Одним словом, '</dev/null' - это ввод из /dev/null .
Спасибо сказали:
Аватара пользователя
seisros
Сообщения: 78
ОС: Calculate 13.04

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение seisros »

alkesta писал(а):
29.05.2013 23:41
Что-то я не понимаю, вывести из ничего в ffmpeg пустоту!?


Вы думали это перенаправление потока или ошибки? Я думаю что он устанавливает пустое значение. Да и по кускам я судить не могу. У меня лишь базовые знания. Я по профессии программист техник. Сложно знать всё от php до nasm.
Многие говорят что трудно жить по высшему закону. А спать трудно? А пробуждаться?
Спасибо сказали:
Аватара пользователя
sgfault
Сообщения: 586
Статус: -

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение sgfault »

По поводу скрипта. Все-таки попробуйте еще раз:
1. Поставить echo вместо вызова ffmpeg. Допустим, 'echo A'. Буква А будет выведена 101 раз?
2. Если да, поставить вместо вызова ffmpeg вызов вот такого скрипта:

Код: Выделить всё

$ cat lspp.sh
#!/bin/sh

set -euf

j=0
echo "Overall number: $#"
echo "Cmd: "
echo -n "$1 "
shift
for i; do
    echo -n "\"$i\" "
    j=$((j + 1))
done
echo

который пишет количетсво своих аргументов и сами аргументы в двойных кавычках. Те вызов должен выглядеть как-то так:

Код: Выделить всё

./lspp.sh ffmepg -i (ну и тд)

Потом попробуйте скопировать в консоль одну из команд на строчке после "Cmd: " в выводе этого скрипта. Она сработает?
Спасибо сказали:
Аватара пользователя
seisros
Сообщения: 78
ОС: Calculate 13.04

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение seisros »

sgfault писал(а):
30.05.2013 00:02

Я вот не понимаю почему вы так пишите? Проще =+1 или ++. Вы по одним учебникам чтоли учитесь?
Многие говорят что трудно жить по высшему закону. А спать трудно? А пробуждаться?
Спасибо сказали:
Аватара пользователя
alkesta
Сообщения: 345
ОС: Fedora

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение alkesta »

sgfault писал(а):
30.05.2013 00:02
По поводу скрипта. Все-таки попробуйте еще раз:
1. Поставить echo вместо вызова ffmpeg. Допустим, 'echo A'. Буква А будет выведена 101 раз?
2. Если да, поставить вместо вызова ffmpeg вызов вот такого скрипта:

Код: Выделить всё

$ cat lspp.sh
#!/bin/sh

set -euf

j=0
echo "Overall number: $#"
echo "Cmd: "
echo -n "$1 "
shift
for i; do
    echo -n "\"$i\" "
    j=$((j + 1))
done
echo

который пишет количетсво своих аргументов и сами аргументы в двойных кавычках. Те вызов должен выглядеть как-то так:

Код: Выделить всё

./lspp.sh ffmepg -i (ну и тд)

Потом попробуйте скопировать в консоль одну из команд на строчке после "Cmd: " в выводе этого скрипта. Она сработает?

1. Пробовал. Пока писал скрипт, стояла заглушка из нескольких echo с выводом значений переменных. 101 вывод был.
2. Завтра попробую.
3. Про "Cmd:" пока не понял, заврался посмотрю.

ps
Спасибо за участие.
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4823
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение SLEDopit »

seisros писал(а):
29.05.2013 23:20
Это не ноль как многие считают это именно "не что".
Вообще-то многие считают, что 0 - это /dev/zero, а никак не /dev/null. (:
seisros писал(а):
30.05.2013 00:07
Я вот не понимаю почему вы так пишите? Проще =+1 или ++. Вы по одним учебникам чтоли учитесь?
++ / =+1 башизм же. а во всех учебниках настоятельно рекомендуют не использовать их без крайней необходимости. (:
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
alkesta
Сообщения: 345
ОС: Fedora

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение alkesta »

seisros писал(а):
30.05.2013 00:07
sgfault писал(а):
30.05.2013 00:02

Я вот не понимаю почему вы так пишите? Проще =+1 или ++. Вы по одним учебникам чтоли учитесь?

А какая разница? Это абсолютно ни на что не влияет. Мне более информативна конструкция x=x+1.

Лучше что-нибудь по существу напиши ;)
Спасибо сказали:
Аватара пользователя
alkesta
Сообщения: 345
ОС: Fedora

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение alkesta »

seisros писал(а):
29.05.2013 23:57
alkesta писал(а):
29.05.2013 23:41
Что-то я не понимаю, вывести из ничего в ffmpeg пустоту!?


Вы думали это перенаправление потока или ошибки? Я думаю что он устанавливает пустое значение.

Я думаю, что ffmpeg каким-то образом нарушает потоковую работу скрипта.
</dev/null & непонятным для меня образом это решает.
PS
ffmpeg почему-то выводит в STDERR а не в STDOUT, потому в первом скрипте применена 2>&1
Спасибо сказали:
Аватара пользователя
alkesta
Сообщения: 345
ОС: Fedora

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение alkesta »

sgfault писал(а):
30.05.2013 00:02
2. Если да, поставить вместо вызова ffmpeg вызов вот такого скрипта:

Код: Выделить всё

$ cat lspp.sh
#!/bin/sh

set -euf

j=0
echo "Overall number: $#"
echo "Cmd: "
echo -n "$1 "
shift
for i; do
    echo -n "\"$i\" "
    j=$((j + 1))
done
echo

который пишет количетсво своих аргументов и сами аргументы в двойных кавычках. Те вызов должен выглядеть как-то так:

Код: Выделить всё

./lspp.sh ffmepg -i (ну и тд)


Вот вывод, приведу только последние 2-е строки, так как там все идентично:

Код: Выделить всё

-----------cut--------------
Overall number: 23
Cmd:
ffmpeg "-i" "Жизнь_Пи.m4b" "-ss" "21247.040000" "-t" "927.982" "-sn" "-acodec" "copy" "-metadata" "title=Часть 3. Больница Бенито Хуарес, Томатлан, Мексика. Глава 99. ч.2" "-metadata" "artist=Янн Мартел" "-metadata" "album=Жизнь Пи" "-metadata" "date=2003" "-metadata" "genre=Audiobook" "-metadata" "track=100" "./Жизнь Пи/100.m4a"
Overall number: 23
Cmd:
ffmpeg "-i" "Жизнь_Пи.m4b" "-ss" "22175.021667" "-t" "315.895" "-sn" "-acodec" "copy" "-metadata" "title=Часть 3. Больница Бенито Хуарес, Томатлан, Мексика. Глава 100." "-metadata" "artist=Янн Мартел" "-metadata" "album=Жизнь Пи" "-metadata" "date=2003" "-metadata" "genre=Audiobook" "-metadata" "track=101" "./Жизнь Пи/101.m4a"


Ну и соотвественно, команда из Cmd: отрабатывает нормально, если у аргументов убрать кавычки.
Спасибо сказали:
Аватара пользователя
sgfault
Сообщения: 586
Статус: -

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение sgfault »

alkesta писал(а):
30.05.2013 10:07
Ну и соотвественно, команда из Cmd: отрабатывает нормально, если у аргументов убрать кавычки.

А если не убирать? Разве не работает? Кавычки не должны ни на что не влиять.

Но это ладно. Я тут подумал, что ведь, наверно, вы были правы насчет ввода: ffmpeg чего-то ждет на вводе (хотя я не знаю чего, тк никогда им не пользовался), и, когда он запускается в вашем цикле, он там (на вводе) находит файл chapter.list (дескрипторы наследуются). Он его прочитывает до конца, и, соответственно, `while read`-у больше нечего читать на втором проходе, и цикл завершается (выполнившись только 1 раз).

Если это объяснение правильное, то оба следующих варианта должны работать.
Первый - это ваш, только без асинхронного запуска ('&'): просто добавьте к вызову ffmpeg перенаправление ввода '</dev/null', те должно быть что-то такое

Код: Выделить всё

ffmpeg -i "$INPUTFILE" -ss "$START_POS" -t "$DURATION" -sn -acodec copy \
      -metadata title="$TITLE" -metadata artist="$ARTIST" -metadata album="$ALBUM" \
      -metadata date="$YEAR_DATE" -metadata genre="$GENRE" -metadata track="$TRACK" "./$ALBUM/$TRACK.m4a" </dev/null

Обратите внимание, в конце нету '&'.

Второй - это попробовать сделать все в точности, как оно происходит при запуске с консоли. Добавьте следующее:

Код: Выделить всё

exec 7<chapter.list;        # Открыть файл chapter.list на чтение для основного процесса на 7-м дескрипторе.
while read -u7 LINE; do    # Чтение идет теперь из 7-го дескриптора.
...(тут все без изменений)..
done

Обратите внимание, что ввод ffmpeg-а в этом примере перенаправлять в /dev/null не нужно. А также ввод цикла while перенаправлять в chapter.list тоже не нужно.
Спасибо сказали:
Аватара пользователя
alkesta
Сообщения: 345
ОС: Fedora

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение alkesta »

sgfault писал(а):
30.05.2013 13:57
alkesta писал(а):
30.05.2013 10:07
Ну и соотвественно, команда из Cmd: отрабатывает нормально, если у аргументов убрать кавычки.

А если не убирать? Разве не работает? Кавычки не должны ни на что не влиять.

С кавычками ffmpeg выводит приллашение к вводу >.
sgfault писал(а):
30.05.2013 13:57
Но это ладно. Я тут подумал, что ведь, наверно, вы были правы насчет ввода: ffmpeg чего-то ждет на вводе (хотя я не знаю чего, тк никогда им не пользовался), и, когда он запускается в вашем цикле, он там (на вводе) находит файл chapter.list (дескрипторы наследуются). Он его прочитывает до конца, и, соответственно, `while read`-у больше нечего читать на втором проходе, и цикл завершается (выполнившись только 1 раз).

Если это объяснение правильное, то оба следующих варианта должны работать.
Первый - это ваш, только без асинхронного запуска ('&'): просто добавьте к вызову ffmpeg перенаправление ввода '</dev/null', те должно быть что-то такое

Код: Выделить всё

ffmpeg -i "$INPUTFILE" -ss "$START_POS" -t "$DURATION" -sn -acodec copy \
      -metadata title="$TITLE" -metadata artist="$ARTIST" -metadata album="$ALBUM" \
      -metadata date="$YEAR_DATE" -metadata genre="$GENRE" -metadata track="$TRACK" "./$ALBUM/$TRACK.m4a" </dev/null

Обратите внимание, в конце нету '&'.

Да, действительно все работает как надо. Спасибо!
sgfault писал(а):
30.05.2013 13:57
Второй - это попробовать сделать все в точности, как оно происходит при запуске с консоли. Добавьте следующее:

Код: Выделить всё

exec 7<chapter.list;        # Открыть файл chapter.list на чтение для основного процесса на 7-м дескрипторе.
while read -u7 LINE; do    # Чтение идет теперь из 7-го дескриптора.
...(тут все без изменений)..
done

Обратите внимание, что ввод ffmpeg-а в этом примере перенаправлять в /dev/null не нужно. А также ввод цикла while перенаправлять в chapter.list тоже не нужно.

Этот пока не пробовал. Но уже нет необходимости пробовать :)
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 21258
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение Bizdelnick »

alkesta писал(а):
30.05.2013 14:20
С кавычками ffmpeg выводит приллашение к вводу >.

Значит, какую-то кавычку Вы не закрыли.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
alkesta
Сообщения: 345
ОС: Fedora

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение alkesta »

Bizdelnick писал(а):
30.05.2013 14:32
alkesta писал(а):
30.05.2013 14:20
С кавычками ffmpeg выводит приллашение к вводу >.

Значит, какую-то кавычку Вы не закрыли.

Да, Вы правы! Последнюю случайно не скопировал...
Спасибо сказали:
Аватара пользователя
sgfault
Сообщения: 586
Статус: -

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение sgfault »

alkesta писал(а):
30.05.2013 14:20
sgfault писал(а):
30.05.2013 13:57
Второй - это попробовать сделать все в точности, как оно происходит при запуске с консоли. Добавьте следующее:

Код: Выделить всё

exec 7<chapter.list;        # Открыть файл chapter.list на чтение для основного процесса на 7-м дескрипторе.
while read -u7 LINE; do    # Чтение идет теперь из 7-го дескриптора.
...(тут все без изменений)..
done

Обратите внимание, что ввод ffmpeg-а в этом примере перенаправлять в /dev/null не нужно. А также ввод цикла while перенаправлять в chapter.list тоже не нужно.

Этот пока не пробовал. Но уже нет необходимости пробовать :)

Ну, необходимости может и нет, но для подтверждения объяснения это было бы полезно. Так что, если есть возможность, я прошу вас все-таки попробовать.
Спасибо сказали:
Аватара пользователя
alkesta
Сообщения: 345
ОС: Fedora

Re: Где-то зарылась ошибка в цикле. Помогите найти

Сообщение alkesta »

sgfault писал(а):
30.05.2013 14:52
Ну, необходимости может и нет, но для подтверждения объяснения это было бы полезно. Так что, если есть возможность, я прошу вас все-таки попробовать.

Код: Выделить всё

#!/bin/sh

TRACK=0
READY=false
INPUTFILE="$1"

ARTIST=`cat chapter.list | awk '/artist:/' | sed '/album_artist:/d' | sed 's/artist: //'`
ALBUM_ARTIST=`cat chapter.list | awk '/album_artist:/' | sed 's/album_artist: //'`
ALBUM=`cat chapter.list | awk '/album:/' | sed '/album_artist:/d' | sed 's/album: //'`
GENRE=`cat chapter.list | awk '/genre:/' | sed 's/genre: //'`
YEAR_DATE=`cat chapter.list | awk '/date:/' | sed 's/date: //'`

mkdir "$ARTIST - $ALBUM"

exec 7<chapter.list;

while read -u7 LINE; do

  if [[ "$LINE" == *title* ]]; then
      TRACK=$(( $TRACK + 1))
      OUTFILE=`printf '%03d\n' "$TRACK"`
      READY=true
      TITLE=`echo $LINE | awk '/title:/' |  sed 's/title: //'`
  else
      READY=false
  fi

  if [[ "$LINE" == *hapter* ]]; then
      START_POS=`echo $LINE | awk '/Chapter/ {print $4}' | sed 's/,*$//'`
      END_POS=`echo $LINE | awk '/Chapter/ {print $6}'`
      DURATION=`echo "$END_POS $START_POS" | awk '{print $1 - $2}'`
  fi

  if [[ "$READY" == true ]]; then
      ffmpeg -i "$INPUTFILE" -ss "$START_POS" -t "$DURATION" -sn -acodec libmp3lame \
      -metadata title="$TITLE" -metadata artist="$ARTIST" -metadata album="$ALBUM" \
      -metadata date="$YEAR_DATE" -metadata genre="$GENRE" -metadata track="$TRACK" \
      "./$ARTIST - $ALBUM/$OUTFILE.mp3"
  fi

done


Работает!

Код: Выделить всё

$ cat chapter.list
album: Смерть на брудершафт 5 - Странный человек
artist: Борис Акунин
album_artist: Борис Акунин
genre: Детектив
date: 2012
Chapter #0.0: start 0.000000, end 258.740000
title: Видение сонное, к худу
Chapter #0.1: start 258.740000, end 876.437075
title: Воронье гнездо
Chapter #0.2: start 876.437075, end 1267.414580
title: 24 часа назад. 24 года назад
Chapter #0.3: start 1267.414580, end 2136.700000
title: Новое задание
Chapter #0.4: start 2136.700000, end 2220.988322
title: Видение зерцальное, всегдашнее
Chapter #0.5: start 2220.988322, end 2492.174172
title: Ее светлость
Chapter #0.6: start 2492.174172, end 3470.802494
title: Роковая ночь. Средь бушующих волн
Chapter #0.7: start 3470.802494, end 3555.532086
title: Видение явное, соблазное
Chapter #0.8: start 3555.532086, end 4393.842086
title: В чертогах большого света
Chapter #0.9: start 4393.842086, end 5429.057506
title: Вот и он. А между тем назревал скандал
Chapter #0.10: start 5429.057506, end 5916.885420
title: Все пропало. В последующие два дня
Chapter #0.11: start 5916.885420, end 6489.675420
title: Чудо на Гороховой
Chapter #0.12: start 6489.675420, end 6818.818322
title: И завязался узелок...
Chapter #0.13: start 6818.818322, end 6893.865420
title: Видение малое, предвестное
Chapter #0.14: start 6893.865420, end 7604.604989
title: Под чаек и беседушка
Chapter #0.15: start 7604.604989, end 8283.022494
title: Наконец момент настал...
Chapter #0.16: start 8283.022494, end 9228.585420
title: Нет, не прост! У «камельгера Степки». Той же ночью, перед рассветом
Chapter #0.17: start 9228.585420, end 9583.340000
title: Успех, полный успех!
Chapter #0.18: start 9583.340000, end 10383.638753
title: Та, кого не ждали. И ведь как в воду глядел… Тимо решает проблему
Chapter #0.19: start 10383.638753, end 11162.854172
title: Дождались! Полчаса спустя. Ужасные минуты
Chapter #0.20: start 11162.854172, end 11841.317732
title: Утомительные хлопоты близились к концу. В вагоне третьего класса

Все откодировано:

Код: Выделить всё

$ ls 'Борис Акунин - Смерть на брудершафт 5 - Странный человек'
001.mp3  004.mp3  007.mp3  010.mp3  013.mp3  016.mp3  019.mp3
002.mp3  005.mp3  008.mp3  011.mp3  014.mp3  017.mp3  020.mp3
003.mp3  006.mp3  009.mp3  012.mp3  015.mp3  018.mp3  021.mp3


Файл на выходе:

Код: Выделить всё

$ ffmpeg -i ./'Борис Акунин - Смерть на брудершафт 5 - Странный человек'/003.mp3
---------------------cut----------------------------
Input #0, mp3, from './Борис Акунин - Смерть на брудершафт 5 - Странный человек/003.mp3':
  Metadata:
    title           : 24 часа назад. 24 года назад
    artist          : Борис Акунин
    album           : Смерть на брудершафт 5 - Странный человек
    date            : 2012
    genre           : Детектив
    track           : 3
    major_brand     : M4B
    minor_version   : 0
    compatible_brands: M4B mp42isom
    creation_time   : 2012-03-31 22:06:18
    album_artist    : Борис Акунин
    disc            : 1
    comment         : Rip by Terr_UA for rutracker.org
    encoder         : Lavf53.5.0
  Duration: 00:06:31.02, start: 0.000000, bitrate: 64 kb/s
    Stream #0.0: Audio: mp3, 44100 Hz, stereo, s16, 64 kb/s
Спасибо сказали: