Jump to content

Executar comandos do terminal num script python


Recommended Posts

Posted

Boas...

 

Hoje decidi experimentar uma coisa em python mas ainda não consegui obter quaisquer resultados.

 

Queria fazer um script em python para me executar um programa no terminal várias vezes, enviando-lhe parâmetros diferentes.

 

Então o que fiz, foi ainda pouco. A validação de dados fica para depois tal como outros aspectos:

 

import os, sys 

feat_codes = {0x1C001, 0x1C002, 0x1C004, 0x1C008, 0x1C020, 0x1C040, 0x1C080,0x1C0FF}

for var in feat_codes:
    print 'Generating {} license key!'.format(var)
    os.popen('./rigup', 'license', sys.argv(1), var)

 

Eu quero receber um parâmetro quando executo o script e usar esse parâmetro no comando que depois quero executar no terminal, mas estou a obter o seguinte erro (já não estou muito recordado das listas):

 

Traceback (most recent call last):
  File "test.py", line 7, in <module>
    os.popen('./rigup', 'license', sys.argv(1), var)
TypeError: 'list' object is not callable

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Posted

PsySc0rpi0n,

O teu erro foi utilizar sys.argv(1) em vez de sys.argv[1], motivo pelo qual recebes o erro de que uma lista não é um objecto que possas invocar (sys.argv é uma lista, não é uma função).

Posted

Ok, já vou alterar...

 

Outra coisa, preciso que os valores presentes naquela lista feat_codes, sejam apresentados em format hex, tal como os coloquei na lista. Isto é difícil de fazer, ou nem por isso?

Pesquisei na net mas aparecem algumas soluções, mas parecem-me um bocado diabólicas!

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Posted

Já foste ler a documentação da os.popen()? Estás a utilizá-la erradamente.

De qualquer modo, eventualmente será mais apropriado utilizares o módulo subprocess (é mais aconselhado).

Posted
import subprocess, sys 

feat_codes = {0x1C001, 0x1C002, 0x1C004, 0x1C008, 0x1C020, 0x1C040, 0x1C080,    0x1C0FF}

for var in feat_codes:
    print 'Generating {} license key!'.format(var)
    subprocess.call('./rigup', 'license', sys.argv[1], var)

 

Dá o seguinte erro:

Traceback (most recent call last):
  File "test.py", line 7, in <module>
    subprocess.call('./rigup', 'license', sys.argv[1], var)
  File "/usr/lib/python2.7/subprocess.py", line 522, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/usr/lib/python2.7/subprocess.py", line 659, in __init__
    raise TypeError("bufsize must be an integer")
TypeError: bufsize must be an integer

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Posted

A documentação muitas vezes pouco ou nada ajuda. Eu li logo a primeira parte, vi o exemplo e tentei aplicar o exemplo ainda que o exemplo pouco tenha a ver com a descrição que é feita acima!

 

Senão repara, a função ou seja lá o que aquilo fôr, é apresentada da seguinte maneira:

subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)

Não dizem o que faz o '*', nem se os outros argumentos são obrigatórios nem nada! Não fui ler as FUA...

Depois o exemplo que dão, não corresponde em quase nada à descrição que acabaram de fazer porque não dizem em cima que temos que usar aspas para separar cada argumento nem que os argumentos têm que estar agrupados com parêntesis rectos e não usam nenhum dos argumentos restantes.

 

Sim eu esqueci-me de colocar os parêntesis rectos e estava a usar plicas em vez de aspas, mas mesmo depois de alterar isso, os erros são os mesmos ou parecidos!

Traceback (most recent call last):
  File "test.py", line 7, in <module>
    subprocess.call(["./rigup", "license", sys.argv[1], var])
  File "/usr/lib/python2.7/subprocess.py", line 522, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1335, in _execute_child
    raise child_exception
TypeError: execv() arg 2 must contain only strings

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Posted

No link que te dei eles remetem alguns pormenores para a documentação da função subprocess.Popen(), onde está escrito que args é uma string ou uma lista de strings. As coisas estão lá escritas, podem é dar mais ou menos trabalho de ler/compreender.

Quanto ao erro que tens agora, provavelmente deve-se ao facto de var ser um número e não uma string.

Posted

E isso quer dizer que tenho que converter para string??? Mas e depois quando o script é execuatdo, este parâmetro é passado como string ou como um valor??? É que tem que ser um valor mesmo e tem que ir em hex format!

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Posted

Repensa o que acabaste de dizer: todos os programas recebem os seus argumentos sob a forma de uma string, e é por isso que a subprocess.call() pede uma lista de strings para passar como argumentos ao programa.

Portanto (só para que não haja dúvidas), tens que decidir se pretendes passar ao programa um número ou decimal ou hexadecimal. Em qualquer dos casos, precisas de converter isso para uma string. Em qualquer dos casos, o programa invocado recebe uma string, como sempre recebeu se o invocasses directamente na linha de comandos.

Se isto não respondeu à tua dúvida, então não compreendi qual é a dúvida e deverás explicar-te melhor.

Posted

@pwseo, se eu não tivesse dúvidas, não tinha colocado a questão. Depois d ler o que escreveste, eu passei a saber de algo que não sabia, daí ter aparecido a minha dúvida, por isso, a questão que eu coloquei, que até pode não ter sido colocada da melhor das formas, tem (tinha) todo o sentido para mim! Eu desconhecia o facto de todos os programas receberem os parâmetros como strings, daí a minha preocupação em enviar o parâmetro para o programa que pretendo lançar no terminal no formato correcto, inteiro neste caso, apesar de saber que o python não trata as variáveis segundo um tipo de dados pre-definido como em C, pelo menos aos olhos de quem não sabe muito de python.

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Posted

@PsySc0rpi0n,

Quando invocas um programa na linha de comandos escreves uma string, correcto? A shell não sabe se tu estás a escrever um número inteiro, um número com casas decimais ou até um símbolo qualquer. Sabe apenas que escreveres caracteres. E é isso que a shell passa ao programa que invocas. Estavas a assumir que as coisas eram bem mais complexas do que são na realidade.

Digo-te mais até: tu já sabias (ou devias saber) que isto funciona assim, pois quando estudaste C utilizaste argc e argv, onde se evidenciava bem este mecanismo 🙂

Posted

Sim, aí tens razão, usei o argc e o argv. Mas nunca usei de forma extensiva e apesar de saber que quando lançamos um programa na consola passando parâmetros, apenas escrevemos caractéres, nunca me ocorreu pensar sobre esse aspecto. Sim, estaria subentendido que se argv é um array de caractéres, à partida o programa recebe esses parâmetros como caractéres/strings, mas nunca pensei neste aspecto porque nunca precisei!

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Posted

Bom, mesmo assim não me ocnsigo livrar do erro!

import subprocess, sys 

feat_codes = ['0x1C001', '0x1C002',
              '0x1C004', '0x1C008',
              '0x1C020', '0x1C040',
              '0x1C080', '0x1C0FF']

for var in feat_codes:
    print 'Generating {} license key!'.format(var)
    subprocess.call(["./rigup", "license", sys.argv[1], var])

Eu antes acho que tinha a lista mal construída. Usei {} em vez de []. E já não me recordo se usar plicas ou aspas é indiferente ou não, mas testei as duas e não funcionou! 

 

O erro:

Traceback (most recent call last):
  File "/home/narayan/programming/python/test.py", line 10, in <module>
    subprocess.call(["./rigup", "license", sys.argv[1], var])
IndexError: list index out of range

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Posted
import os 

feat_codes = ['0x1C001', '0x1C002',
              '0x1C004', '0x1C008',
              '0x1C020', '0x1C040',
              '0x1C080', '0x1C0FF']

for var in feat_codes:
    print 'Generating {} license key!'.format(var)
    os.system("./rigup license " + var)
Posted

Bom aqui fica uma solução que funcionou:

 

import os, sys 

feat_codes = ["0x1C001", "0x1C002",
              "0x1C004", "0x1C008",
              "0x1C020", "0x1C040",
              "0x1C080", "0x1C0FF"]

for var in feat_codes:
    print 'Generating {} license key!'.format(var2)
    os.system("~/Downloads/rigol/rigup_mso1104z/./rigup license " + sys.argv[1] + " " + var)

Mas ainda vou tentar com o subprocess.call.

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Posted

@PsySc0rpi0n,

Algumas clarificações: em Python as listas declaram-se com [], e as strings tanto podem ser "assim" como 'assim' (pessoalmente, prefiro 'assim', mas é indiferente).

Mas vamos agora ao que interessa:

13 horas atrás, PsySc0rpi0n disse:

Bom, mesmo assim não me ocnsigo livrar do erro!

Bem, tu conseguiste livrar-te de um erro, mas agora apareceu outro: IndexError: list index out of range. Muito provavelmente isso deve-se ao sys.argv[1] que estás a utilizar ali no código -- estavas a invocar o script passando-lhe um argumento? Porque se não estivesses, o erro estaria completamente justificado.

De qualquer modo, e para que não fique incerteza no ar relativamente à forma como as coisas funcionam (que é simples!), ficam aqui dois pequenos scripts que simulam o teu problema facilmente:

#!/usr/bin/python3
# Este será o ficheiro 'rigup'

from sys import argv

print('{} called with arguments {!r}'.format(argv[0], argv[1:]))
#!/usr/bin/python3
# E este será o ficheiro 'test.py'

import sys
import subprocess

feat_codes = [ '0x1c001', '0x1c002', '0x1c004', '0x1c008',
               '0x1c020', '0x1c040', '0x1c080', '0x1c0ff' ]

for var in feat_codes:
    subprocess.call([ './rigup', 'license', sys.argv[1], var ])

E agora, assumindo que temos estes ficheiros numa directoria psy, aqui fica a transcrição da sessão no terminal:

~/psy $ # Cá estão os ficheiros que criámos
~/psy $ ls -lh
total 8,0K
-rw-rw-r-- 1 apc apc 107 Out  2 12:08 rigup
-rw-rw-r-- 1 apc apc 244 Out  2 11:57 test.py
~/psy $
~/psy $ # Vamos permitir a execução do 'rigup'
~/psy $ chmod +x rigup
~/psy $
~/psy $ # Vamos testar o rigup
~/psy $ ./rigup um dois tres quatro
./rigup called with arguments ['um', 'dois', 'tres', 'quatro']
~/psy $ 
~/psy $ # E agora vamos executar o test.py sem argumentos adicionais
~/psy $ python3 test.py 
Traceback (most recent call last):
  File "test.py", line 8, in <module>
    call([ './rigup', 'license', argv[1], code ])
IndexError: list index out of range
~/psy $ # ^-- Cá está o erro que obtiveste da última vez
~/psy $ 
~/psy $ # Mais uma vez, agora com o argumento adicional
~/psy $ python3 test.py argumento-adicional
./rigup called with arguments ['license', 'argumento-adicional', '0x1c001']
./rigup called with arguments ['license', 'argumento-adicional', '0x1c002']
./rigup called with arguments ['license', 'argumento-adicional', '0x1c004']
./rigup called with arguments ['license', 'argumento-adicional', '0x1c008']
./rigup called with arguments ['license', 'argumento-adicional', '0x1c020']
./rigup called with arguments ['license', 'argumento-adicional', '0x1c040']
./rigup called with arguments ['license', 'argumento-adicional', '0x1c080']
./rigup called with arguments ['license', 'argumento-adicional', '0x1c0ff']
~/psy $ # Funcionou.

E é isto.

  • Vote 1
Posted (edited)

Não percebi o problema do "list index out of range"...

Para além disso, eu preciso de receber um parâmetro quando executo o script test.py que é a localização de um ficheiro.

Ainda estou a tentar perceber como é a syntaxe mas aconselhada para o subprocess.call mas ainda não dei com ela!

PS: estou com o python 2.7.9, acho eu!

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

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
×
×
  • Create New...

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.