Запуск скрипта bash с использованием модуля VTE

Я пытаюсь использовать модуль VTE для запуска сценария Bash: у меня есть несколько ошибок, одна из них:

avconv version 9.11-6:9.11-2ubuntu2, Copyright (c) 2000-2013 the Libav developers
  built on Mar 24 2014 06:12:33 with gcc 4.8 (Ubuntu 4.8.2-17ubuntu1)
: No such file or directory

Вот часть моего скрипта Python:

def download(self, a, donnees=None):                
      adresse = self.champ.get_text()
      self.v.fork_command('./pluzz.sh', '-u', adresse)  # calling the bash script
[...]
def __init__(self):       
      self.v = vte.Terminal()
      self.v.set_emulation('xterm')
      self.v.show()
      self.box1.add(self.v)

И кусок скрипта bash:

echo -e "$VERT""DEBUT DU TRAITEMENT""$NORMAL"

#Recuperation de l' ID de l' emission
UserAgent='Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:19.0) Gecko/20100101 Firefox/19.0'
ID=$(wget -q -U "${UserAgent}" "${URL}" -O - | grep -E "og:url.*content.*http://*" | sed 's+.*,\([0-9]*\).*+\1+g')

#wget du json conteant les infos
echo -e "$ROSE""-->RECUPERATION DU JSON""$NORMAL"
JSON="$(wget -q -U "${UserAgent}" "http://webservices.francetelevisions.fr/tools/getInfosOeuvre/v2/?idDiffusion=${ID}&catalogue=Pluzz&callback=webserviceCallback_${ID}" -O - | sed 's+\\/+/+g')"

#Recuperation des infos
echo -e "$ROSE""-->TRAITEMENT DU JSON""$NORMAL"
DATE="$(echo "${JSON}" | sed 's+.*date_debut..\"\([^\"]*\)\".*+\1+g')"
PROG="$(echo "${JSON}" | sed 's+.*code_programme..\"\([^\"]*\)\".*+\1+g')"
M3U="$(echo "${JSON}" | sed 's+.*url..\"\([^\"]*m3u8\)\".*+\1+g')"

#Recuperation du master M3U et traitement
echo -e "$BLEU""-->RECUPERATION DU FICHIER VIDEO""$NORMAL"
M3U2="$(wget -q -U "'Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:19.0) Gecko/20100101 Firefox/19.0'" "${M3U}" -O - | grep -E ".*index_2.*")"

avconv -i "${M3U2}" -vcodec copy -acodec copy "${PROG}_${ID}.mkv"

Скрипт bash хорошо работает в консоли:

:~./pluzz.sh http://pluzz.francetv.fr/videos/coluche_un_clown_ennemi_d_etat.html
DEBUT DU TRAITEMENT
-->RECUPERATION DU JSON
-->TRAITEMENT DU JSON
-->RECUPERATION DU FICHIER VIDEO
avconv version 9.11-6:9.11-2ubuntu2, Copyright (c) 2000-2013 the Libav developers
  built on Mar 24 2014 06:12:33 with gcc 4.8 (Ubuntu 4.8.2-17ubuntu1)
[hls,applehttp @ 0x1ebfe00] max_analyze_duration reached
Input #0, hls,applehttp, from 'http://ftvodhdsecz-f.akamaihd.net/i/streaming-adaptatif_france-dom-tom/2014/S18/J5/101152365-20140502-,398,632,934,k.mp4.csmil/index_2_av.m3u8?null=':
  Duration: 00:56:10.00, start: 0.100667, bitrate: 0 kb/s
    Stream #0.0: Video: h264 (Main), yuv420p, 704x396 [PAR 1:1 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 50 tbc
    Stream #0.1: Audio: aac, 48000 Hz, stereo, fltp
    Stream #0.2: Data: [21][0][0][0] / 0x0015

Я надеюсь, что мое объяснение понятно... Спасибо

Изменить: я нашел решение: заменить

self.v.fork_command('./pluzz.sh', '-u', adresse)

от

self.v.fork_command(None, ['/bin/bash', '-u', './pluzz.sh', adresse])

1 ответ

Я думаю, что ваша проблема связана с:

  self.v.fork_command('./pluzz.sh', '-u', adresse)  # calling the bash script

который предполагает две вещи:

  1. что скрипт находится в том же каталоге, откуда было запущено приложение;
  2. что сценарий является исполняемым и может быть запущен как самостоятельный

но для 2. в скрипте отсутствует #!/bin/bash заголовок shebang, сообщающий системе, что это сценарий оболочки, который необходимо выполнить, и для 1. вам лучше использовать абсолютный путь или путь относительно файла текущего модуля.

Вместо этого вы должны использовать путь относительно текущего скрипта или абсолютный путь:

import sys
import os
### if the pluzz script is in same directory as your python app
pluzz_script = os.path.join(os.path.dirname(sys.argv[0]), 'pluzz.sh')
### explicitely run bash, to have it run your script
self.v.fork_command('/bin/bash', pluzz_script, '-u', address)

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

Ваша проблема в том, что на самом деле файл не был загружен или не может быть записан и avconv не могу получить к нему доступ. Сложно сказать что не так как скрипт не пускает wgetвыходной. Хотя вам лучше конвертировать этот скрипт в python и использовать безопасный временный каталог, чтобы загрузить файл и обработать его.

Вот перевод вашего скрипта на python:

# echo -e "$VERT""DEBUT DU TRAITEMENT""$NORMAL"
# retrieval of the show's id

from lxml import etree
import subprocess
import requests
import json
import os

### User defined values:
url='http://pluzz.francetv.fr/videos/doctor_who.html'
target_path=os.path.join(os.environ['HOME'], 'Downloads')
###

headers={'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:19.0) Gecko/20100101 Firefox/19.0'}

##### ID=$(wget -q -U "${UserAgent}" "${URL}" -O - | grep -E "og:url.*content.*http://*" | sed 's+.*,\([0-9]*\).*+\1+g')
p = etree.HTML(requests.get(url, headers=headers).text)
show_id = p.xpath('//meta[@property="og:url"]/@content')[0].split(',')[-1].split('.')[0]

##### get the JSON containing the show's data
##### JSON="$(wget -q -U "${UserAgent}" "http://webservices.francetelevisions.fr/tools/getInfosOeuvre/v2/?idDiffusion=${ID}&catalogue=Pluzz&callback=webserviceCallback_${ID}" -O - | sed 's+\\/+/+g')"
show_data_url = "http://webservices.francetelevisions.fr/tools/getInfosOeuvre/v2/?idDiffusion={show}&catalogue=Pluzz&callback=webserviceCallback_{show}"
show_data = json.loads("".join(requests.get(show_data_url.format(show=show_id), headers=headers).text.split('(')[1:])[:-1])

# retrieve data from the json
##### DATE="$(echo "${JSON}" | sed 's+.*date_debut..\"\([^\"]*\)\".*+\1+g')"
##### PROG="$(echo "${JSON}" | sed 's+.*code_programme..\"\([^\"]*\)\".*+\1+g')"
##### M3U="$(echo "${JSON}" | sed 's+.*url..\"\([^\"]*m3u8\)\".*+\1+g')"
# date = show_data['diffusion']['date_debut']
# prog = show_data['code_programme']
# m3u = list(filter(lambda x: x['format'] == 'm3u8-download', j['videos']))[0]['url']

p = requests.get(list(filter(lambda x: x['format'] == 'm3u8-download', show_data['videos']))[0]['url'], headers=headers).text

# M3U retrieval
##### M3U2="$(wget -q "${M3U}" -O - | grep -E ".*index_2.*")"
video_url = list(filter(lambda l: "index_2" in l, p.split()))[0]

##### avconv -i "${M3U2}" -vcodec copy -acodec copy "${PROG}_${ID}.mkv"

dest_file = "{}_{}.mkv".format(show_data['code_programme'], show_id)
subprocess.call(['avconv', '-i', video_url, '-vcodec', 'copy', '-acodec', 'copy', os.path.join(target_path, dest_file)])

или вы можете использовать для обработки avconvвыход:

p = subprocess.Popen(['avconv', '-i', video_url, '-vcodec', 'copy', '-acodec', 'copy', os.path.join(target_path, dest_file)], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()

for line in out:
    print(out)

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

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

НТН

Другие вопросы по тегам