Why does importing subprocess change my output? - python

I noticed the following using Python 2.5.2 (does not occur using 2.7):
#!/usr/bin/python
import sys
for line in sys.stdin:
print line,
Output:
$ echo -e "one\ntwo\nthree" | python test.py
$ one
$ two
$ three
as expected. However, if I import subprocess to the this script:
#!/usr/bin/python
import sys
import subprocess
for line in sys.stdin:
print line,
Output:
$ echo -e "one\ntwo\nthree" | python test.py
$ two
$ three
What happened to the first line of output?
Update:
I think I may have discovered the root of the problem. I had a file named time.py in my cwd. A time.pyc is being created every time I run the script with subprocess imported, suggesting that ./time.py is also being imported. The script runs normally if I delete the .pyc and time.py files; however, there is still the question of why a subprocess import would cause ./time.py to be imported as well?
I have narrowed it down even further to the exact line in time.py that causes the strange behaviour. I have stripped down the working dir and file content to just that which affects the output:
test.py
#!/usr/bin/python
import sys
import subprocess
for line in sys.stdin:
print line,
time.py
#!/usr/bin/python
import sys
for line in sys.stdin:
hour = re.search(r'\b([0-9]{2}):', line).group(1)
Running test.py with any kind of input results in the first line of output being omitted and time.pyc being created.

Sounds like your local time.py will be imported instead of the global time module. You might want to rename it, or at least start checking if it was run as a script or imported as a module.
This will prove it for you if you want to test it.
#!/usr/bin/python
import sys
# Test that script was run directly
if __name__=='__main__':
for line in sys.stdin:
hour = re.search(r'\b([0-9]{2}):', line).group(1)
else:
print 'Imported local time.py instead of global time module!'
sys.exit(1)

print line, before 2.7 did not put out a newline so it overwrote the first line. Lose the comma and the result will be the same.

Related

run a python script from another python script

i have a test script test.py inside which i am trying to run one more python script bexec.app(this is a python script). Actually test.py is just for my testing. The original script is a lengthy one and bexec.app is getting called inside in a command line.
I tried this
#!/usr/bin/python
import os, sys
os.path.insert(0, 'current bexec script path')
import bexec.app
But this does not work -
Traceback (most recent call last):
File "test", line 5, in <module>
import bexec.pphshaper
ImportError: No module named bexec.app
I donot want to change the bexec.app script to bexec_app.py because this follows some naming convention
bexec.app also has #!/usr/bin/python inside it.
how can i import my bexec script inside test.py
You seem to want to run your bexec, not import it. And if so, regular
os.system('current bexec script path')
should be sufficient
Dot means subpackage structure to python, but it's still possible with imp.
below is bexec.app sample file:
#!/usr/bin/python
a = 2
and this is how you can import it in your test.py file, look below for the code:
#!/usr/bin/python
import os, sys, imp
my_module = imp.load_source('my_module', 'bexec.app')
print (my_module.a)

Python script doesn't print output in command prompt

I need some advice with a Python script. I'm still new and learned it by myself. I found the script on Google. After I retype it, it doesn't print the result in the console. How can the result of the script be shown in the console? Details as below:
C:\Python27>test1.py af8978b1797b72acfff9595a5a2a373ec3d9106d
C:\Python27>
After I press enter, nothing happens. Should the result be shown or not?
Here's the code that I retyped:
#!/usr/bin/python
#coding: ascii
import requests
import sys
import re
url = 'http://hashtoolkit.com/reverse-hash?hash='
try:
hash = sys.argv[1]
except:
print ("usage: python "+sys.argv[0]+" hash")
sys.exit()
http = request.get(url+hash)
content = http.content
cracked = re.findall("<span title=\*decrypted (md5|sha1|sha384|sha512) hash\*>(.*)</span>", content) # expression regular
print ("\n\tAlgoritmo: "+cracked[0][0])
print ("\tPassword Cracked: "+cracked[0][1])
The first line in your script is called a Shebang line.
A Shebang line tells the script to run the Python interpreter from that location.
The shebang line you provided is a Linux system path, but it looks from the path you are executing Python from, that you are running on Windows.
You can do one of two things here to fix that:
Remove the Shebange Line.
Remove the first line from your script.
Execute the script using python test1.py COMMAND_LINE_ARGUMENTS
Modify Your Shebang line.
Change the first line of your script from !/usr/bin/python to
#!python (This is assuming that python is in your systems PATH variable.)`
Execute the script using test1.py COMMAND_LINE_ARGUMENTS
Also, you are trying to import the requests module that is not installed in the standard library.
If you haven't installed this yet, you can do so by going to your Python install directory and go to the scripts folder.
Hold shift and right click and go Open command window here
Type pip install requests and hit enter.
After that you should be good to go, execute the script by navigating to it and type test.py COMMAND_LINE_ARGUMENT
If a Python script doesn't have the shebang line:
python test.py COMMAND_LINE_ARGUMENT
you need to run your script using python. try:
C:\Python27>python test1.py af8978b1797b72acfff9595a5a2a373ec3d9106d

Python: Trying to restart script not working

Tried to restart my python script within itself.
Python 2.7.11
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import sys
os.execv(__file__, sys.argv)
sys.exit()
Result:
Traceback (most recent call last):
File "...\foo.py", line 3, in <module>
os.execv(__file__, sys.argv)
OSError: [Errno 8] Exec format error
Another code:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import sys
os.execv(sys.executable, [sys.executable] + sys.argv)
sys.exit()
Result:
C:\...\python.exe: can't open file 'C:\...\Math': [Errno 2] No such file or directory
The file's name is foo.py - it's in a folder name 'Math Project'
Codepage: 852, if necessary.
Your error message C:\...\python.exe suggests that you're running a Windows system.
Your first script fails because under Windows, os.execv() doesn't know how to handle Python scripts because the first line (#!/usr/bin/python) is not evaluated nor does it point to a valid Python interpreter on most Windows systems. In effect, os.execv() tries to execute a plain text file which happens to contain Python code, but the system doesn't know that.
Your second script fails to correctly retrieve the file name of your Python script foo.py. It's not clear to me why that happens, but the error message suggests that there might be a problem with the space in your directory name Math Project.
As a possible workaround, try replacing the line
os.execv(sys.executable, [sys.executable] + sys.argv)
by the following:
os.execv(sys.executable,
[sys.executable, os.path.join(sys.path[0], __file__)] + sys.argv[1:])
This line attempts to reconstruct the correct path to your Python script, and pass it as an argument to the Python interpreter.
As a side note: Keep in mind what your script is doing: it's unconditionally starting another instance of itself. This will result in an infinite loop, which will eventually bring down your system. Make sure that your real script contains an abort condition.
EDIT:
The problem lies, indeed, with the space in the path, and the workaround that I mentioned won't help. However, the subprocess module should take care of that. Use it like so:
import os
import sys
import subprocess
subprocess.call(["python", os.path.join(sys.path[0], __file__)] + sys.argv[1:])
Try this:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import sys
os.execv(sys.executable, [sys.executable, '"' + sys.argv[0] + '"'] + sys.argv[1:])
Double quotation marks can help windows ignore that space.
It worked for me :)

Why can't the import command be found?

I am using the input function from fileinput module to accept script via pipes or input file Here is the minimum script:
finput.py
import fileinput
with fileinput.input() as f:
for line in f:
print(line)
After making this script executable, I run ls | ./finput.py and get unexpected error message
./finput.py: line 1: import: command not found
./finput.py: line 3: syntax error near unexpected token `('
./finput.py: line 3: `with fileinput.input() as f:'
The only fix I found is when I add #!/usr/bin/env/python3 before the import statement.
But this issue seems to be related only to the fileinput module. Since the following script worked well without a shebang:
fruit.py
import random
fruits = ["mango", "ananas", "apple"]
print(random.choice(fruits))
Now what am I missing? Why can't the import command be found since the shebang is not required in finput.py?
Your need to tell your OS that this is a Python program, otherwise, it's interpreted as a shell script (where the import command cannot be found).
Like you identified, this is done by using a shebang line:
#!/usr/bin/env python3
This is only needed if you are going to run your script like this: ./script.py, which tells your OS "run this executable". Doing so requires that your OS identify how it's supposed to run the program, and it relies on the shebang line for that (among other things).
However if you run python script.py (which I'm guessing you did for fruit.py), then Python does not ask your OS whether that is a Python program or not, so the shebang line doesn't matter.

How to run a python script from IDLE interactive shell?

How do I run a python script from within the IDLE interactive shell?
The following throws an error:
>>> python helloworld.py
SyntaxError: invalid syntax
Python3:
exec(open('helloworld.py').read())
If your file not in the same dir:
exec(open('./app/filename.py').read())
See https://stackoverflow.com/a/437857/739577 for passing global/local variables.
In deprecated Python versions
Python2
Built-in function: execfile
execfile('helloworld.py')
It normally cannot be called with arguments. But here's a workaround:
import sys
sys.argv = ['helloworld.py', 'arg'] # argv[0] should still be the script name
execfile('helloworld.py')
Deprecated since 2.6: popen
import os
os.popen('python helloworld.py') # Just run the program
os.popen('python helloworld.py').read() # Also gets you the stdout
With arguments:
os.popen('python helloworld.py arg').read()
Advance usage: subprocess
import subprocess
subprocess.call(['python', 'helloworld.py']) # Just run the program
subprocess.check_output(['python', 'helloworld.py']) # Also gets you the stdout
With arguments:
subprocess.call(['python', 'helloworld.py', 'arg'])
Read the docs for details :-)
Tested with this basic helloworld.py:
import sys
if len(sys.argv) > 1:
print(sys.argv[1])
You can use this in python3:
exec(open(filename).read())
The IDLE shell window is not the same as a terminal shell (e.g. running sh or bash). Rather, it is just like being in the Python interactive interpreter (python -i). The easiest way to run a script in IDLE is to use the Open command from the File menu (this may vary a bit depending on which platform you are running) to load your script file into an IDLE editor window and then use the Run -> Run Module command (shortcut F5).
EASIEST WAY
python -i helloworld.py #Python 2
python3 -i helloworld.py #Python 3
Try this
import os
import subprocess
DIR = os.path.join('C:\\', 'Users', 'Sergey', 'Desktop', 'helloword.py')
subprocess.call(['python', DIR])
execFile('helloworld.py') does the job for me. A thing to note is to enter the complete directory name of the .py file if it isnt in the Python folder itself (atleast this is the case on Windows)
For example, execFile('C:/helloworld.py')
In a python console, one can try the following 2 ways.
under the same work directory,
1.
>> import helloworld
# if you have a variable x, you can print it in the IDLE.
>> helloworld.x
# if you have a function func, you can also call it like this.
>> helloworld.func()
2.
>> runfile("./helloworld.py")
For example:
import subprocess
subprocess.call("C:\helloworld.py")
subprocess.call(["python", "-h"])
In Python 3, there is no execFile. One can use exec built-in function, for instance:
import helloworld
exec('helloworld')
In IDLE, the following works :-
import helloworld
I don't know much about why it works, but it does..
To run a python script in a python shell such as Idle or in a Django shell you can do the following using the exec() function. Exec() executes a code object argument. A code object in Python is simply compiled Python code. So you must first compile your script file and then execute it using exec(). From your shell:
>>>file_to_compile = open('/path/to/your/file.py').read()
>>>code_object = compile(file_to_compile, '<string>', 'exec')
>>>exec(code_object)
I'm using Python 3.4. See the compile and exec docs for detailed info.
I tested this and it kinda works out :
exec(open('filename').read()) # Don't forget to put the filename between ' '
you can do it by two ways
import file_name
exec(open('file_name').read())
but make sure that file should be stored where your program is running
On Windows environment, you can execute py file on Python3 shell command line with the following syntax:
exec(open('absolute path to file_name').read())
Below explains how to execute a simple helloworld.py file from python shell command line
File Location: C:/Users/testuser/testfolder/helloworld.py
File Content: print("hello world")
We can execute this file on Python3.7 Shell as below:
>>> import os
>>> abs_path = 'C://Users/testuser/testfolder'
>>> os.chdir(abs_path)
>>> os.getcwd()
'C:\\Users\\testuser\\testfolder'
>>> exec(open("helloworld.py").read())
hello world
>>> exec(open("C:\\Users\\testuser\\testfolder\\helloworld.py").read())
hello world
>>> os.path.abspath("helloworld.py")
'C:\\Users\\testuser\\testfolder\\helloworld.py'
>>> import helloworld
hello world
There is one more alternative (for windows) -
import os
os.system('py "<path of program with extension>"')

Categories