У меня есть скрипт, который кодирует видео каждый день (cron job), и это видео загружается на YouTube сразу после его создания. Хотя иногда эти сценарии терпят неудачу.

Как я могу сделать скрипт, чтобы повторить эти две команды, если одна из них или обе не удаются?

Сценарий:

#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

echo $(date)
cd /home/pi/
ls *.jpg > stills.txt

DATE=$(date --date=yesterday +"%Y-%m-%d")
three_days_ago=$(date --date="3 days ago" "+%m-%d")
yesterday=$(date --date yesterday "+%m-%d")
video_name=$(date +"%m-%d")


mencoder -nosound -ovc lavc -lavcopts vcodec=mpeg4:aspect=16/9:vbitrate=8000000 -vf scale=1920:1080 -o $yesterday.avi -mf type=jpeg:fps=10 mf://@stills.txt

video_link=$(youtube-upload --email=xxx --password=xxx--title="Timelapse Video of "$yesterday --description="Heraklion Timelapse Video of "$yesterday  \
--category=Tech --keywords="Raspberry PI, Timelapse" /home/pi/$yesterday.avi) 
echo $video_link
youtube-upload --email=xxx --password=xxx--add-to-playlist http://gdata.youtube.com/feeds/api/playlists/PLbjjzh8UkLN2pQTZwXyQ4kP2bXb7Zwtmo $video_link


echo $(date)
/home/pi/Desktop/camera/Dropbox-Uploader/dropbox_uploader.sh upload /home/pi/Desktop/camera/video_maker.log /Public/pi_videos
find . -type f -name $DATE\* -exec rm {} \;
rm $three_days_ago.avi

Команды, которые я хочу реализовать:

  • mencoder -nosound ....
  • video_link = $(youtube-upload --email = xxx ...

1 ответ1

1

Вы можете заключить две важные команды в цикл:

max_retries=3
for i in $(seq ${max_retries});do
    critical_command
    if [ $? == 0 ];then
        break
    fi
done

$? хранит код возврата последней команды. "0" означает успех, все остальное означает провал. В квадратных скобках я сравниваю этот код возврата с "0". Если они равны, сравнение выдает "true", что означает, что мы вводим блок "if" (если вы используете это, обратите внимание на пробелы в скобках, они важны). Там я запускаю один "break", который сообщает циклу for, что он должен завершиться немедленно, и не делать дальнейших итераций. Вкратце: если критическая_команда прошла успешно, продолжайте работу с остальной частью программы.

Это также работает, если выходные данные вашей команды перехвачены в переменной, как в вашей video_link. Для инструмента загрузки, возможно, было бы целесообразно добавить небольшую повторную попытку паузы, поскольку сервер может быть занят:

critical_command
sleep 10 # wait for 10 seconds

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .