LINUX.ORG.RU

Как выполнить Linux команду из Django views?


0

0

Django работает через Apache так:
<VirtualHost *:80>
...
<Location «/»>
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE alexkarta_com.settings
PythonDebug On
PythonPath «['/home/asuslin/']+sys.path»
</Location>
...
</VirtualHost>

Хочу выполнять скипты linux из views.py. Думал о таком принципе работы, пользователь в форме задает параметры, после, чего запускается linux команда в зависимости от введенных данных. пытался так (функция из views.py):

def tides_gms(request):
import os, subprocess
values = (int(request.GET['s']), int(request.GET['y']), int(request.GET['m']), int(request.GET['d']), int(request.GET['h']), int(request.GET['m']),int( request.GET['dis']), int(request.GET['p']))
command = «cd ~/alexkarta_com/models/tides_gms/;Rscript tides.r -mode 1 -station %d -y %d -m %d -d %d -h %d -min %d -dis %d -p %d»
command = command % values
os.system(command)
p = subprocess.Popen('iconv -f CP866 -t UTF8 ~/alexkarta_com/models/tides_gms/Lelop.dat ', shell=True, stdout=subprocess.PIPE)
out = p.stdout.readlines()
return render_to_response('tides_gms_result.html', {'out':out})

Здесь я задумывал следующее. tides_gms получает request сформированный формой, command - строка для выполнения в linux shell, формирующаяся в сооветсвии с GET. tides.r запускает кучу мелких программ, которые генерируют результат в растр (путь к нему прописан в шаблоне) и текстовый файл ~/alexkarta_com/models/tides_gms/Lelop.dat, который я задумывал переконвертировать в utf8 и отобразить на странице с растром. Так понял, что вызывать просто через os.system не получится. Подскажите, как решить вопрос?

> Django

(int(request.GET['s']), int(request.GET['y']), int(request.GET['m']), int(request.GET['d']), int(request.GET['h']), int(request.GET['m']),int( request.GET['dis']),


Почему ты напрямую используешь request.GET?

Почему бы не воспользоваться питоновским модулем iconv,
если тебе просто надо перекодировать файлы?

Sphinx ★★☆☆
()
Ответ на: комментарий от Sphinx

>Почему ты напрямую используешь request.GET? А как правильно?

Почему бы не воспользоваться питоновским модулем iconv

Да, верно, сделаю питоновским

alexkarta
() автор топика
Ответ на: комментарий от alexkarta

> А как правильно?

Через urls.py привязать части URL к аргументам вида.

Sphinx ★★☆☆
()

>p = subprocess.Popen('iconv -f CP866 -t UTF8 ~/alexkarta_com/models/tides_gms/Lelop.dat ', shell=True, stdout=subprocess.PIPE)

вот это сила

dimon555 ★★★★★
()

>Так понял, что вызывать просто через os.system не получится.

Почему вы так думаете? У меня прекрасно вызывается через os.system:

cmd = 'pdflatex ' + nume_fisier + '; mv ' + str(numar) + '.pdf img/'

os.system(cmd)

gnunixon ★★★
()
Ответ на: комментарий от gnunixon

Всем спасибо, все действительно работает. Запустил через subprocess.Popen, подправил в соответствии с замечаниями. Всем большое спасибо за внимание и подсказки. Сделал глупую примитивную ошибку, зачем-то в путях прописывал ~/ вместо home/wwwd/. Погулял, расслабился, открыл файл и осенило. Очень удобная функция subprocess.Popen.stdout.readlines(), читающая стандартный вывод в переменную, подскажате, пожалуйста, функцию, записывающую ошибки в переменную? С ходу не нашел, нужно для отладки

alexkarta
() автор топика
Ответ на: комментарий от alexkarta

Ошибки чего? subprocess? В мануалах есть пример. А если ошибки вообще - то лови исключение и всё, там в except ты можешь на него посмотреть.

anonymous
()
Ответ на: комментарий от anonymous

Вроде бы во всем разобрался. Оказывается, можно протестить, как будут выполняться скрипты через терминал благодаря команде sudo su www-data. Т.о. удалось отловить все проблемы с правами доступа и все заработало. Примерно так выглядит работающая функция (понимаю, что ее вид смешен для опытных разработчиков, буду дальше изучать Django):
def tides_gms(request):
import os
values = int(request.GET['station']), int(request.GET['year']),int(request.GET['month']), int(request.GET['day']),int(request.GET['hour']), int(request.GET['minute']),int(request.GET['discr']),int( request.GET['period'])
command=«cd /home/asuslin/alexkarta_com/models/tides_gms/; Rscript tides.r -mode 1 -station %d -y %d -m %d -d %d -h %d -min %d -dis %d -p %d»
command = command % values
os.system('rm -rf /home/asuslin/alexkarta_com/static/media/tmp/tides_gms.png')
os.system(command)
os.system('iconv -f CP866 -t UTF8 /home/asuslin/alexkarta_com/models/tides_gms/Lelop.dat>/home/asuslin/alexkarta_com/static/template/tides_gms_tmp')
return render_to_response('tides_gms_result.html', glob_vars)

alexkarta
() автор топика
Ответ на: комментарий от alexkarta

Ты бы задачу описал детальнее, может ее по-другому можно решить?

KDE41user
()
Ответ на: комментарий от alexkarta

Научись лоркоду. Без разметки питон нечитабелен.

values = int(request.GET['station']),

В urls.py впиши же свой r'/fcking_url/([0-9]+)/....', а лучше даже с naming, далее в объявлении функции views-а вкрути def fckingview(request, station, ...)

command=«cd /home/asuslin/alexkarta_com/models/tides_gms/; Rscript tides.r -mode 1 -station %d -y %d -m %d -d %d -h %d -min %d -dis %d -p %d»

1. Пути в какие-нибудь переменные впиши

2. Никогда не бери из GET-а (и вообще от пользователя) что-то, и подставляй в os.system. Они тебе такого понапишут, что потом диск чистым станет. Валидируй до невозможности, придумай функцию для конвертирования введённых данных в реальные (чтобы вводились какие-нибудь коды, а функция преобразовывала в реальные значения, убирая хакирские варианты).

3. Воткни, таки, subprocess - он гибче и приятнее.

И главное - лови везде все возможные для программы эксепшены.Не вообще все, а именно возможные в данной ситуации, продумай код, потестируй, поймай места возможных ошибок. Чтобы стало ясно, когда ошибка из-за логики программы, а когда из-за отсутствующих данных, например.

И почитай насчёт питоновских врапперов для системных команд - всё-таки оно удобнее и портабельнее, чем вызов сторонних прог, пусть и не всегда.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.