Jump to content
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

zephirus

Correr script phyton por php

Recommended Posts

zephirus

Olá,

Não sei se esta secção é a correcta para colocar esta questão, se não for peço desde já desculpa.

Tenho um site que está a correr numa lan e pretendo correr um script python através de php. Na verdade, penso que o problema esteja mesmo no script em si pois eu consigo chamar o script. O problema é que apenas parte do resultado aparece, coisa que não acontece caso eu corra o script directamente na linha de comandos. Estou a usar windows para correr o script. Em baixo, o script:

#!C:/Python27/python

from __future__ import print_function
from array import *
from time import gmtime, strftime

import os
import time
import subprocess
import sys
import re
import time

import urllib

def get_os(ip):
 cmd = "C:\\paexec.exe \\\\"+ip+" -low -u <username> -p <password> REG QUERY \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\" /v ProductName"
 CommandOutput, stderrText = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT ).communicate()
 t=str(CommandOutput)
 t1 = t.split("REG_SZ")[1]
 t2 = t1.split('Connecting')[0]
 t3 = t2.replace(" ","")
 t4 = t3.replace("\n","")
 t5 = t4.replace("\r","")
 t6 = t5.replace("\t","")
 return t6

opener = urllib.FancyURLopener({})
f = opener.open("http://10.46.12.36/sites/default/files/machine_data/ips.txt")
text = f.read()
ip_f = text.split()
f.close()

f2 = open('C:\\xampp\\htdocs\\sites\\default\\files\\machine_data\\output.txt','w')

f2.write("guid;ip;os" + "\n")

computer_os = {}

for i in range (0, len(ip_f)):
 ip = ip_f[i]

 pause_time = 0.1

 print('======================================================')
 print(' GETTING INFO FOR ' + ip_f[i])
 print('======================================================')
 res = subprocess.call(['ping', ip, '-n', '1'])
 if res == 0:
computer_os[i] = get_os(ip)
time.sleep(pause_time)
comments[i] = 'OK'

f2.write(ip + ";" + ip + ";" + computer_os[i])
   f2.write("\n")
 else:
time.sleep(pause_time)
computer_os[i] = ''

f2.write(ip + ";" + ip + ";" + computer_os[i])
f2.write("\n")

f2.close()

O que eu consigo obter deste script é apenas a criação do ficheiro "output.txt" mas apenas com o header:

guid;ip;os

O que é suposto aparecer, no caso do ficheiro "ips.txt" ter apenas um ip, por exemplo, seria:

guid;ip;os

10.10.5.36;10.10.5.36;Windows7

Alguém sabe se há algum problema no script?

Obrigado.

Edited by zephirus
GeSHi

Share this post


Link to post
Share on other sites
taviroquai

Viva,

Já experimentaste

<?php
exec('c:\caminho\para\python meu_script.py', $output);

Por outro lado... não consegues fazer o mesmo que esse script faz com PHP? Pelo que vejo precisas ler da registry do Windows (ver http://phpmaster.com/access-the-windows-registry-from-php/) e trabalhar com ficheiros (ver http://php.net/manual/pt_BR/book.filesystem.php) ... Usavas apenas PHP o que podia ser uma vantagem...

Edited by taviroquai

Share this post


Link to post
Share on other sites
zephirus

Viva,

Já experimentaste

<?php
exec('c:\caminho\para\python meu_script.py', $output);

Por outro lado... não consegues fazer o mesmo que esse script faz com PHP? Pelo que vejo precisas ler da registry do Windows (ver http://phpmaster.com/access-the-windows-registry-from-php/) e trabalhar com ficheiros (ver http://php.net/manual/pt_BR/book.filesystem.php) ... Usavas apenas PHP o que podia ser uma vantagem...

Obrigado taviroquai,

De facto eu apenas quero o resultado do script. A maneira de o obter pode ser uma qualquer desde que funcione. O problema é que eu preciso de aceder ao registro mas de múltiplas máquinas na rede e não apenas na local onde está o server. Esse link que enviaste parece-me restringir o acesso apenas à própria máquina. É possível fazer isso para múltiplas?

Em relação ao comando que puseste, já testei mas infelizmente acontece aquilo que descrevi em cima. Apenas o header do ficheiro é preenchido...

Share this post


Link to post
Share on other sites
zephirus

Tentei de novo o script e da primeira vez deu timeout no site (após 30seg) e obtive apenas o cabeçalho. De seguida tentei de novo e já não faz timeout e o resultado é o mesmo. O que eu pretendo mesmo é iniciar o script no servidor, nem sequer preciso de obter retorno nenhum por php pois estou a usar outro método para ir buscar a informação.

Share this post


Link to post
Share on other sites
Pedro C.

Eu não percebo totalmente o teu código (a falta de identação deixa algumas hipóteses em aberto) mas se eu percebi o problema parece que o que não resultou foi o que devia ter acontecido no "if" ou no "else" (que é onde se escreve os ips, já agora estou a assumir que todo o código abaixo de "for i in range (0, len(ip_f)):" está totalmente dentro deste ciclo).

Para fazer debug mete um print logo a seguir a sacares o res (print res) e depois um print para cada um dos if/else. Isto para perceber se ele não escreveu por causa do código dentro do "if/else" ou se nem sequer chegou a entrar dentro dessas condições.

Já agora não sei se é importante mas tu abres um ficheiro com a variável "f" mas nunca chegas a fecha-lo (não sei se é necessário no urllib), e depois voltas a abrir outro ficheiro, desta com python nativo, com a mesma variável "f" e também nunca chegas a fecha-lo (f.close()). Tenta ver se o facto de não fechares o ficheiro é o que está a impedir que os dados fiquem gravados lá dentro (é só uma possibilidade).

Share this post


Link to post
Share on other sites
zephirus

Eu não percebo totalmente o teu código (a falta de identação deixa algumas hipóteses em aberto) mas se eu percebi o problema parece que o que não resultou foi o que devia ter acontecido no "if" ou no "else" (que é onde se escreve os ips, já agora estou a assumir que todo o código abaixo de "for i in range (0, len(ip_f)):" está totalmente dentro deste ciclo).

Para fazer debug mete um print logo a seguir a sacares o res (print res) e depois um print para cada um dos if/else. Isto para perceber se ele não escreveu por causa do código dentro do "if/else" ou se nem sequer chegou a entrar dentro dessas condições.

Já agora não sei se é importante mas tu abres um ficheiro com a variável "f" mas nunca chegas a fecha-lo (não sei se é necessário no urllib), e depois voltas a abrir outro ficheiro, desta com python nativo, com a mesma variável "f" e também nunca chegas a fecha-lo (f.close()). Tenta ver se o facto de não fechares o ficheiro é o que está a impedir que os dados fiquem gravados lá dentro (é só uma possibilidade).

Olá Pedro,

Editei o código em cima com identação. Alterei as variáveis dos ficheiros e neste momento fecho também os ficheiros abertos Coloquei também alguns prints no código e entro tanto dentro do ciclo for e também no case res == 0. No entanto o problema mantém-se...

Estas operações demoram algum tempo, não sei se isto tem alguma coisa a ver...

Share this post


Link to post
Share on other sites
Pedro C.

Não percebi. Os prints não servem para resolver o problema, servem para perceber onde ele está. No output que prints é que sairam?

Já agora dá algum erro o teu script?

Share this post


Link to post
Share on other sites
zephirus

Não percebi. Os prints não servem para resolver o problema, servem para perceber onde ele está. No output que prints é que sairam?

Já agora dá algum erro o teu script?

Eu sei que os prints não resolvem. No output saem os prints todos correctos que devem sair. Não obtenho qualquer erro. O problema não está no script em si, quase de certeza, está é na chamada por php. Não entendo é o motivo visto que o php chama o script sem problemas.

Share this post


Link to post
Share on other sites
Pedro C.

Então e o "ip_f"? Tem a lista que é suposto?

Se calhar o problema é o link. Eu pelo menos não consigo abri-lo e o browser diz-me: "The connection has timed out".

Sendo assim ele escreve header mas não faz o ciclo for porque a lista ip_f não existe (ou tem comprimento zero). Mas nesse caso deverias obter um erro quando tentas abrir o link, e mesmo que não desse nunca deveriam ter aparecido os prints dado que o len do ip_f seria 0.

Share this post


Link to post
Share on other sites
zephirus

Então e o "ip_f"? Tem a lista que é suposto?

Se calhar o problema é o link. Eu pelo menos não consigo abri-lo e o browser diz-me: "The connection has timed out".

Sendo assim ele escreve header mas não faz o ciclo for porque a lista ip_f não existe (ou tem comprimento zero). Mas nesse caso deverias obter um erro quando tentas abrir o link, e mesmo que não desse nunca deveriam ter aparecido os prints dado que o len do ip_f seria 0.

O link é interno, é normal que não consigas aceder :) Mas o problema não está ai, esse feed funciona.

Share this post


Link to post
Share on other sites
zephirus

Progressos!

Se alterar a função get_os(ip): e colocar um return de texto manualmente (return 'xtpo' por exemplo), já consigo preencher o ficheiro f2, ou seja, aparentemente, chamando o script por php encalha nas chamadas do paexec.exe.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.