os module, trying to recognize the path of a file - python

I built this little program called Assembler.py:
def main(argv):
temp = os.path.realpath(argv[1])
if temp.endswith(".asm"):
print(temp)
else:
print("submit a valid file")
if __name__ == "__main__":
main(sys.argv)
I'm running this with some script I built:
python Assembler.py $1
example for running:
Assembler pong.asm
I don't know why if is wrong. Why my address is not ending with .asm ?

Your all code like this:
#coding=utf-8
import os
import sys
def main(argv):
temp = os.path.realpath(argv[1])
if temp.endswith(".asm"):
print(temp)
else:
print("submit a valid file")
if __name__ == "__main__":
main(sys.argv)
Then, you should use python Assembler pong.asm directly.
Example:
C:\Users\ou\Desktop\test>python test.py xyz.asm
C:\Users\ou\Desktop\test\xyz.asm

There is nothing wrong with the if. The problem is with the shell script and the way you are trying to run it.
If you want to run your python code directly you should run
python Assembler.py pong.asm
The .py extension is important!
If you want to write simple shell script to wrap that. You can create file named Assembler with following content:
python Assembler.py $1
To run that simple shell script you should run:
./Assembler pong.asm
or
sh Assembler pong.asm
Where ./ or sh is required.

Related

Use os.execvp() to call Python script (with Tkinter based GUI) via pkexec and setting environment variables before

This is a follow-up question of Use tkinter based PySimpleGUI as root user via pkexec.
I have a Python GUI application. It should be able to run as user and as root. For the latter I know I have to set $DISPLAY and $XAUTHORITY to get a GUI application work under root. I use pkexec to start that application as root.
I assume the problem is how I use os.getexecvp() to call pkexec with all its arguments. But I don't know how to fix this. In the linked previous question and answer it works when calling pkexec directly via bash.
For that example the full path of the script should be/home/user/x.py.
#!/usr/bin/env python3
# FILENAME need to be x.py !!!
import os
import sys
import getpass
import PySimpleGUI as sg
def main_as_root():
# See: https://stackoverflow.com/q/74840452
cmd = ['pkexec',
'env',
f'DISPLAY={os.environ["DISPLAY"]}',
f'XAUTHORITY={os.environ["XAUTHORITY"]}',
f'{sys.executable} /home/user/x.py']
# output here is
# ['pkexec', 'env', 'DISPLAY=:0.0', 'XAUTHORITY=/home/user/.Xauthority', '/usr/bin/python3 ./x.py']
print(cmd)
# replace the process
os.execvp(cmd[0], cmd)
def main():
main_window = sg.Window(title=f'Run as "{getpass.getuser()}".',
layout=[[]], margins=(100, 50))
main_window.read()
if __name__ == '__main__':
if len(sys.argv) == 2 and sys.argv[1] == 'root':
main_as_root() # no return because of os.execvp()
# else
main()
Calling that script as /home/user/x.py root means that the script will call itself again via pkexec. I got this output (self translated to English from German).
['pkexec', 'env', 'DISPLAY=:0.0', 'XAUTHORITY=/home/user/.Xauthority', '/usr/bin/python3 /home/user/x.py']
/usr/bin/env: „/usr/bin/python3 /home/user/x.py“: File or folder not found
/usr/bin/env: Use -[v]S, to takeover options via #!
For me it looks like that the python3 part of the command is interpreted by env and not pkexec. Some is not as expected while interpreting the cmd via os.pkexec().
But when I do this on the shell it works well.
pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY python3 /home/user/x.py
Based on #TheLizzard comment.
The approach itself is fine and has no problem.
Just the last element in the command array cmd. It should be splitted.
cmd = ['pkexec',
'env',
f'DISPLAY={os.environ["DISPLAY"]}',
f'XAUTHORITY={os.environ["XAUTHORITY"]}',
f'{sys.executable}',
'/home/user/x.py']

Error in Importing a bash script into a python

I am trying to create a python script script.py in bash and importing a bash script.
#!/usr/bin/env python
import os
import glob
from fnmatch import fnmatch
# importing a software
python_package = os.system("""#!/path_to_bin/bin/python \
from __future__ import print_function, division \
from python_toolbox.toolbox.some_toolbox import run \
if __name__ == '__main__': \
run()"""
# testing
greeting = "Hello world!"
print(greeting)
Running the script.py in python3
$python3 script.py
File "script.py", line 15
greeting = "Hello world!"
SyntaxError: invalid syntax
Nominally the problem is that you are missing the closing paren on the os.system call. But there is a better way to run a python program than trying to write it all on the command line. Instead, you can pass a full script, including newlines, to python's stdin.
#!/usr/bin/env python
import sys
import subprocess as subp
# importing a software
def run_script():
subp.run([sys.executable, "-"], input=b"""
print("I am a called python script")
""")
# testing
run_script()
greeting = "Hello world!"
print(greeting)
In this script, the second python script is run whenever you call run_script. Notice that the script in the string has to follow the normal python indendation rules. So, there is indentation inside run_script but then the string holding the second script starts its indentation all the way to the left again.

Running one python script from another script with command line argument having executable in it

I am trying to run a python script within another python script. Which will run 10 times and produce 10 outputs.
I want to run program1.py inside program2.py. Now my program1.py was initially taking a C executable inside it and it takes 1 command line argument.
The program1.py looks like below:
import os
import sys
dataset = sys.argv[1]
os.system(f"/home/Dev/c4.5 -u -f {dataset}")
os.system(f"/home/Dev/c4.5rules -u -f {dataset}")
os.system(f"/home/Dev/c4.5rules -u -f {dataset} > Temp")
f = open('Temp')
# Some code
Where c4.5 and c4.5rules are the name of the executable files. To run this I was using python3 program1.py dataset_name
Now I am trying to put this program1.py inside program2.py and I am trying this below approach:
import os
import subprocess
# Some code
for track in range(0, 10):
with open(f'Train_{track}', 'r') as firstfile, open(f'DF_{track}.data', 'w') as secondfile:
for line in firstfile:
secondfile.write(line)
os.system("/home/Dev/program1.py DF_track")
#subprocess.Popen("/home/Dev/program1.py DF_track", shell=True)
Where I simply want to get the output of program1.py 10 times and want to use DF_track as the command line input for each output generation.
Using above approach I am getting lots of error. Please help.
Edit_1 :
Actually whenever I am trying to run, my cursor is not working, it is freezing, so unable to copy the errors.
Here are some of them :
1. attempt to perform an operation not allowed by security policy.
2. syntax error : word expected (expecting ")")
Imagine I have 2 files, the first file is a.py and the other is b.py and I want to call the a.py from b.py.
The content of a.py is:
print('this is the a.py file')
and the content of b.py is:
import os
stream = os.popen('python3 a.py')
output = stream.read()
print(output)
Now when I call b.py from terminal I get the output I expect which is a.py print statment
user#mos ~ % python3 b.py
this is the a.py file
You can do this with subprocess too instead of os module.
Here is a nice blog I found online where I got the code from: https://janakiev.com/blog/python-shell-commands/
See the example below.
a.py
def do_something():
pass
b.py
from a import do_something
do_something()

Cocoa app cannot start looping python script. Works when built/run through xcode

I'm trying to use NSTask to start a looping python script from a cocoa app. The python script ends up in the app's Contents/Resources folder.
I get the path to the script and create the NSTask with:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *scriptPath = [[NSBundle mainBundle] pathForResource:filename ofType:#"py"];
NSTask* task = [[NSTask alloc] init];
task.launchPath = PYTHON_PATH;
task.arguments = [NSArray arrayWithObjects:scriptPath, nil];
[task launch];
[task waitUntilExit];
});
(I've omitted the stdOutPipe stuff for readability)
When I build & run my app from xcode it works as expected, the task holds at waitUntilExit and the python script runs continuously.
When I try to run this from the produced .app file it gets to waitUntilExit, stalls for awhile, and then exits with an error. I have logging in the python script so I know that no part of the script is run during this time. The script path is true to the location of the python scripts and returns the same path when run from xcode or from the .app.
I figure I must have some of the project settings set-up incorrectly, but it seems like its handling resources correctly. Any idea?
Update 1
Running a non-looping python script with just a print statement works for the .app. The followings non-looping script fails as well:
#!/usr/bin/python
import os
def log(string):
print(string)
path = os.environ['PWD'] + '/smoke_screen_test.txt'
f1=open(path, 'a')
f1.write(string + "\n")
if __name__ == '__main__':
log("Test works")
exit(0)
Maybe the import statements mess it up? Or the file creation?
The problem was the use of os.environ['PWD']. PWD does not return the local directory of the script being executed. Duh. Solution is to grab the path of the script from argv[0] and use the directory of that path:
path = os.path.dirname(sys.argv[0])
Then pass path around as needed.

Python3: command not found, when running from cli

I am trying to run my python module as a command, however I am always getting the error: command not found.
#!/usr/bin/env python
import sys
import re
from sys import stdin
from sys import stdout
class Grepper(object):
def __init__(self, pattern):
self.pattern = pattern
def pgreper(self):
y = (str(self.pattern))
for line in sys.stdin:
regex = re.compile(y)
x = re.search(regex, line)
if x:
sys.stdout.write(line)
if __name__ == "__main__":
print("hello")
pattern = str(sys.argv[1])
Grepper(pattern).pgreper()
else:
print("nope")
I am sure whether it has something to do with the line:
if __name__ == "__main__":
However I just can't figure it out, this is a new area for me, and it's a bit stressful.
Your script name should have a .py extension, so it should be named something like pgreper.py.
To run it, you need to do either python pgreper.py pattern_string or if it has executable permission, as explained by Gabriel, you can do ./pgreper.py pattern_string. Note that you must give the script path (unless the current directory is in your command PATH); pgreper.py pattern_string will cause bash to print the "command not found" error message.
You can't pass the pattern data to it by piping, IOW, cat input.txt | ./pgreper.py "pattern_string" won't work: the pattern has to be passed as an argument on the command line. I guess you could do ./pgreper.py "$(cat input.txt)" but it'd be better to modify the script to read from stdin if you need that functionality.
Sorry, I didn't read the body of your script properly. :embarrassed:
I now see that your pgreper() method reads data from stdin. Sorry if the paragraph above caused any confusion.
By way of apology for my previous gaffe, here's a slightly cleaner version of your script.
#! /usr/bin/env python
import sys
import re
class Grepper(object):
def __init__(self, pattern):
self.pattern = pattern
def pgreper(self):
regex = re.compile(self.pattern)
for line in sys.stdin:
if regex.search(line):
sys.stdout.write(line)
def main():
print("hello")
pattern = sys.argv[1]
Grepper(pattern).pgreper()
if __name__ == "__main__":
main()
else:
print("nope")
Make sure you have something executable here : /usr/bin/env.
When you try to run your python module as a command, it will call this as an interpreter. You may need to replace it with /usr/bin/python or /usr/bin/python3 if you don't have an env command.
Also, make sure your file is executable : chmod +x my_module.py and try to run it with ./my_module.py.

Categories

Resources