Showing posts with label BSD. Show all posts
Showing posts with label BSD. Show all posts

Thursday, July 29, 2010

Automate Command-line Programs

I had to automate a command-line program. Then I did this script like a sample that do auto control to vi.

This way is possible control any kind of command-line program.

#!/bin/python

import subprocess
import time
import threading

class ProcessRunner(threading.Thread):
def run(self):
self.process = subprocess.Popen(["vi /tmp/xpto > /tmp/viOutput"], shell = True, bufsize = 1000, stdout = subprocess.PIPE, stdin = subprocess.PIPE, stderr = subprocess.STDOUT)

pr = ProcessRunner()
pr.start()

time.sleep(1)

pr.process.stdin.write("i\n")
pr.process.stdin.flush()

time.sleep(1)

pr.process.stdin.write("Content xpto... :P\n")
pr.process.stdin.flush()

time.sleep(1)

pr.process.stdin.write(chr(27))
pr.process.stdin.flush()

time.sleep(1)

pr.process.stdin.write(":wq\n")
pr.process.stdin.flush()


If is necessary read some content from program output, you can put the output in a temp file, in this case goes to /tmp/viOutput. See with attention the line of the subprocess.Popen. Another way is use the pr.process.stdout but it dont work fine for me.

The command pr.process.stdin.write(chr(27)) write the "character" ESC, like the keyboard key.

Thursday, November 27, 2008

Script Python para consumir Web Services em .Net

Tive um desafio a poucos dias. Que foi consumir Web Services feitos em .Net a partir de um servidor Solaris 10 via processo.

De todas as soluções possíveis que estive a ver, a melhor foi usar Python.

Encontrei este exemplo:

http://users.skynet.be/pascalbotte/rcx-ws-doc/postxmlpython.htm

Assim fiz o WebServiceGenericClientNet.py:

#!/usr/bin/python

# by eduveks

import sys, httplib, array

try:
    host = ""
    url = ""
    namespace = ""
    header = ""
    method = ""
    params = {}

    for arg in sys.argv[1:]:
        if host == "" and arg.find("host=") == 0:
            host = arg[len("host="):]
        elif url  == "" and arg.find("url=") == 0:
            url  = arg[len("url="):]
        elif namespace == "" and arg.find("namespace=") == 0:
            namespace = arg[len("namespace="):]
        elif header == "" and arg.find("header=") == 0:
            header = arg[len("header="):]
        elif method == "" and arg.find("method=") == 0:
            method = arg[len("method="):]
        elif arg.find("param_") == 0:
            params[arg[len("param_"):arg.find("=")]] = arg[arg.find("=") + 1:]

    SOAP_Request = ""
    SOAP_Request += "<soap:Envelope"
    SOAP_Request += " soap:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\""
    SOAP_Request += " xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\""
    SOAP_Request += " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""
    SOAP_Request += " xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\">"
    if header != "":
        SOAP_Request += "<soap:Header>"
        SOAP_Request += header
        SOAP_Request += "</soap:Header>"
    SOAP_Request += "<soap:Body>"
    SOAP_Request += "<"+ method +" xmlns=\""+ namespace +"\">"
    for param in params.keys():
        SOAP_Request += "<"+ param +">"+ params[param] +"</"+ param +">"
    SOAP_Request += "</"+ method +">"
    SOAP_Request += "</soap:Body>"
    SOAP_Request += "</soap:Envelope>"

    http = httplib.HTTP(host)
    http.putrequest("POST", url)
    http.putheader("Host", host)
    http.putheader("User-Agent", "Python")
    http.putheader("Content-type", "text/xml; charset=\"UTF-8\"")
    http.putheader("Content-length", "%d" % len(SOAP_Request))
    http.putheader("SOAPAction", "\""+ namespace + method +"\"")
    http.endheaders()
    http.send(SOAP_Request)

    http_response_statuscode, http_response_statusmessage, http_response_header = http.getreply()
    SOAP_Response = http.getfile().read()
    if http_response_statuscode == 200 and http_response_statusmessage == "OK":
        print SOAP_Response[SOAP_Response.find("<"+ method +"Result>") + len("<"+ method +"Result>"):SOAP_Response.find("</"+ method +"Result>")]
    else:
        print "### ERROR ###############"
        if SOAP_Response.find("<faultstring>") > -1:
            print SOAP_Response[SOAP_Response.find("<faultstring>")  + len("<faultstring>"):SOAP_Response.find("</faultstring>")]
        print "Response: ", http_response_statuscode, http_response_statusmessage
        print http_response_header
        print SOAP_Response

except:
    print "### ERROR ###############"
    for err in sys.exc_info():
        print err


Para executar o script basta dar permissões de execução e executar:

chmod +x WebServiceGenericClientNet.py
./WebServiceGenericClientNet.py host=localhost url=/HelloWorld.asmx namespace=http://tempuri.org/ method=HelloWorld param_strSay=HelloWorld


O output é:

HelloWorld


Os parâmetros do WebServiceGenericClientNet.py são:

host: Endereço do servidor
url: Endereço do web service
namespace: Namespace do web service, que pode ser encontrado vendo o WSDL, http://localhost/HelloWorld.asmx?WSDL
method: Método do web service a ser chamado
param_*NOME_DO_PARAMETRO*: Caso o método precise de parâmetros, podem ser definidos assim, atenção a ordem.

Além de usar este script no Solaris, também acabei por usar este script para chamar web services apartir do .Net/C#, pois são web services que serão atualizados constantemente, com novos métodos e talz, e em vez de ficar atualizando o WSDL, basta chamar diretamente com o script a queima-roupa, e a configuração da chamada dos web services pode ser feita a partir de configurações em base de dados. Para fazer isto no .Net/C# foi só lançar um processo assim:

System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.FileName = "C:\Python26\python.exe";
process.StartInfo.Arguments = "WebServiceGenericClientNet.py host=localhost url=/HelloWorld.asmx namespace=http://tempuri.org/ method=HelloWorld param_strSay=HelloWorld";
process.StartInfo.WorkingDirectory = "C:\Python26\";
process.Start();
string output = process.StandardOutput.ReadToEnd();

O script suporta a configuração do header, passando o argumento header=... para o script.

Para explorar e ver fácilmente os SOAPs enviados e recebidos na chamada de um web service, existe o WebServiceStudio:

Sunday, April 20, 2008

DragonFlyBSD - Instalação de pacotes

Hoje começei a brincar com o DragonflyBSD, e até agora estou gostando, vários detalhes facilitados comparado a outros BSDs.

Mas depois de instalar e ao tentar usar o pkg_search, tive o seguinte erro:


No pkgsrc(7) tree found. Fetching pkg_summary(5) file.
fetch: http://pkgbox.dragonflybsd.org/packages/DragonFly-1.12/i386//All/pkg_summary.bz2: Not Found
fetch: http://pkgbox.dragonflybsd.org/packages/DragonFly-1.10.1/i386//All/pkg_summary.bz2: Not Found
Unable to fetch pkg_summary(5) file.


Tentei abrir estas URLs no browser mas também sem sucesso, então comecei a fuçar e descobri este site:

http://www.pkgsrc-box.org/

Que tem os packages do DragonflyBSD, então fuçando neste site descobri que aqui tem a lista dos packages:

http://www.pkgsrc-box.org/packages/stable/DragonFly-1.10/All/

E também o precioso pkg_summary.bz2:

http://www.pkgsrc-box.org/packages/stable/DragonFly-1.10/All/pkg_summary.bz2

E da versão 1.12 estão aqui:

http://pkgbox.dragonflybsd.org/packages/DragonFly-1.12/stable/All/

Boa, mas agora como configurar para usar estas URLs em vez das que vem por default?! Procurei e procurei no /etc e nada, então resolvi arriscar e fiz:


vi /usr/bin/pkg_search


Boas notícias é um script mesmo e logo nas primeiras linhas estava a string com as preciosas URLs, é preciso dar permissões de escrita no arquivo:


chmod u+w /usr/bin/pkg_search


Mudei as linhas do PKGSRCBOX1 e do PKGSRCBOX2 para:


PKGSRCBOX1=http://pkgbox.dragonflybsd.org/packages/DragonFly-1.12/stable/
PKGSRCBOX2=http://www.pkgsrc-box.org/packages/stable/DragonFly-1.10/


Depois foi só usar o pkg_search, o qual funcionou perfeitamente.


pkg_search nano


Para usar o pkg_add precisei passar a url completa do arquivo, as dependências são instaladas automaticamente se estiverem na mesma URL base:


pkg_add http://pkgbox.dragonflybsd.org/packages/DragonFly-1.12/stable/All/nano-2.0.7.tgz