2013-06-14 2 views
2

У меня есть сценарий bash, который я запускаю с DVD. Этот скрипт копирует многотомные tar-файлы с DVD на локальный компьютер. Напротив копирования, сценарий предлагает пользователю вставить второй DVD, после чего копируются остальные файлы. Сценарий существует на первом DVD, но не на втором.Вывод сценария Bash без ошибок

Этот сценарий просто останавливается после копирования последнего файла, но до запуска операции множественного размножения tar и последующей обработки. Сообщения об ошибках и сообщениях не сообщаются. Я попытался запустить bash с '-x', но нет ничего подозрительного - даже инструкции выхода. Еще более печальным является тот факт, что это поведение непоследовательно. Иногда сценарий останавливается, но в других случаях он будет продолжать без проблем.

У меня есть сценарий на скрипте. После завершения операций копирования, я вижу это:

read(255, "\0\0\0\0\0\0\0\0\0\0"..., 5007) = 1302 
read(255, "", 5007)  = 0 
exit_group(0)    = ? 

Я знаю, что Баш читает файл сценария в память и выполняет его оттуда, но это возможно, что он пытается повторно прочитать файл сценария в какой-то момент и неудача (поскольку он больше не существует)? Файлы tar довольно большие, и это занимает приблизительно 10-15 минут с момента начала сценария до момента копирования последнего файла (со второго DVD).

+0

Есть ли что-нибудь в dmesg, чтобы предположить, что у вас закончилась память или что-то в этом роде? То, что я хотел бы попробовать, - это изменить сценарий, чтобы скопировать себя в локальное хранилище и выполнить его оттуда. – timmins

+0

Спасибо за предложение. Я проверю dmesg. Я на самом деле думал о копировании сценария в/tmp, а затем повторного вызова его оттуда. Моя единственная проблема заключается в том, что родительский скрипт все еще выполнялся с DVD. Предположительно, bash не попытался бы перечитать родительский скрипт до тех пор, пока не завершится дочерний скрипт (после чего я все равно сделаю). – LousyG

+1

Я просто смог воспроизвести его. Ничего в dmesg.Интересно, что я воспроизвел его при запуске «cat/dev/zero>/dev/shm/file» и открыл очень большой файл журнала в vi, пытаясь использовать как можно больше памяти (я добрался до 32M бесплатно!) , Я не уверен, вызвали ли это это, или мне просто повезло, но это стоит отметить. Я собираюсь изменить сценарий, чтобы скопировать себя в/tmp, а затем снова запустить его оттуда. Затем я перепробою. Посмотрим, что произойдет. – LousyG

ответ

3

Я вижу, вы уже нашли обходной путь, так что я просто пытаюсь раскрыть то, что происходит:

bash не читает весь сценарий в памяти, он делает буферном читает на нем, ровно столько, сколько нужно каждый раз (предположительно это для совместного использования кода с терминальным входом). Перед запуском любых внешних команд bash ищет точную позицию в скрипте и продолжает читать оттуда после завершения команды. Вы можете увидеть это, если вы редактируете файл сценария в то время как он работает:

term1$ cat > test.sh 
sleep 8 
echo DONE 
term1$ bash test.sh 

Хотя sleep выполняется, изменить сценарий из другого терминала:

term2$ cat > test.sh 
echo HAHA 

Наблюдайте, как bash запутывается, когда sleep является завершения:

test.sh: line 2: A: command not found 

Он помнит, что позиция в файле ввода был 8 до sleep, поэтому он пытается прочитать оттуда и сталкивается с последним A из перезаписанного скрипта.

Теперь к вашему делу. Как правило, наличие файла, открытого из dvd, блокирует диск и запрещает смену диска. Если вам все же удастся изменить диск, это обязательно должно включать в себя umount, который затем должен аннулировать скрипт fd. Это явно не происходит в соответствии с вашим результатом strace, что немного странно. В любом случае bash не сможет прочитать остальную часть скрипта.

+0

Я думаю, вы абсолютно правы. Все доказательства, которые я могу найти, поддерживают это. Пока что мой рабочий процесс работает. Благодаря! – LousyG

+0

Я скажу, однако, довольно странно, что bash не сообщает о какой-либо ошибке. Вы могли бы подумать, что они могут напечатать сообщение о том, что чтение не удалось. – LousyG

+0

Да, но твоя трасса показывает, что это не подведет! Это странная часть ... она просто вернула кучу нулей, которые bash затем проигнорировали и нажали EOF. – Jester