Re-use of argument after '#' with argparse's fromfile_prefix_chars='#' - python

Original question: I am running a python script
python script.py #runs/run_1/parameters.txt
Is there some way to access the string runs/run_1 in my script?
Actual question: I noticed that what I really need is a little different from the above. Independently from the directory from which I run the script, I need to get the location of parameters.txt.
For example, when I'm running the script from the directory runs/run_1 itself, I still need to get the path. I could do this with os.getcwd().
But when I'm running the code from PyCharm, I pass #/runs/run_1/parameters.txt as a parameter, while the script itself lives in some other directory. Here, I would need to read from sys.argv as suggested in the comments below.
For now I will have to do differentiate these cases with an if-statement checking whether the string before parameters.txt in python script.py #.../parameters.txt is empty. Is there a better way?

Related

python script calling another script

I wrote a python script that works. The first line of my script is reading an hdf5 file
readFile = h5py.File('FileName_00','r')
After reading the file, my script does several mathematical operations, successfully working. In the output I got function F.
Now, I want to repeat the same script for different files. Basically, I only need to modify FileName_00 by FimeName_01 or ....FileName_10. I was thinking to create a script that call this script!
I never wrote a script that call another script, so any advice would be appreciable.
One option: turn your existing code into a function which takes a filename as an argument:
def myfunc(filename):
h5py.file(filename, 'r')
...
Now, after your existing code, call your function with the filenames you want to input:
myfunc('Filename_00')
myfunc('Filename_01')
myfunc('Filename_02')
...
Even more usefully, I definitely recommend looking into
if(__name__ == '__main__')
and argparse (https://docs.python.org/3/library/argparse.html) as jkr noted.
Also, if you put your algorithm in a function like this, you can import it and use it in another Python script. Very useful!
Although there are certainly many ways to achieve what you want without multiple python scripts, as other answerers have shown, here's how you could do it.
In python we have this function os.system (learn more about it here: https://docs.python.org/3/library/os.html#os.system). Simply put, you can use it like this:
os.system("INSERT COMMAND HERE")
Replacing INSERT COMMAND HERE with the command you use to run your python script. For example, with a script named script.py you could conceivably (depending on your environment) include the following line of code in a secondary python script:
os.system("python script.py")
Running the secondary python script would run script.py as well. FWIW, I don't necessarily think this is the best way to accomplish your goal -- I tend to agree with DraftyHat's solution in most circumstances. But in case you were curious, this is certainly an option in python. I've used this functionality in the past, albeit not to run other python scripts, but to execute commands in the shell. Hope this helps!

Distinguish runs from Command Prompt vs Spyder console

I am working on a script that needs to be run both from a command prompt, such as BASH, and from the Console in Spyder. Running from a command prompt allows the script file name to be followed by several arguments which can then be utilized within the script; >python script1.py dataFile.csv Results outputFile.csv. These arguments are referenced within the script as elements of the list sys.argv.
I've tried using subprocess.run("python script1.py dataFile.csv Results outputFile.csv") to enable the console to behave as the command line, but sometimes it works fine and other times it needs certain arguments, like -f between python and the file name, before it will display what is displayed in the command line. Different computers disagree on whether such arguments help or hurt.
I've searched and searched, and found some clever ways to use technicalities of the specific operating system to distinguish, but is there something native to Python I can use?
If you import sys in the console and then call sys.argv, it will show you the value ['']. While running a script within Spyder expands that array to ['script1.py'] (plus the file address), it will still not get larger than one entry.
If, on the other hand, you run the script from the command line the way you showed above, then sys.argv will have a value of ['script1.py', 'dataFile.csv', 'Results', 'outputFile.csv']. You can utilize the differences between these to distinguish between the cases.
What are the best differences to use? You want to distinguish between two possibilities, so an if - else pair would be best in the code. What's true in one case and false in the other? if sys.argv will not work, because in both cases the list contains at least one string, so that will be effectively True in both cases.
if len(sys.argv) > 1 works, and it adds the capability to run from the command line and go with what is coded for the console case.

Running powershell scripts with python under one session

I try to create a python program which will deobfuscate powershell malware, which uses IEX. My python program is actually hooking the IEX function and instead of running the desired string, it will print the string.
Now my problem is that I have some .ps1 scripts (for examples 1.ps1, 2.ps1, etc..) and I want to run all of them under the same session so that by this, all the local variables created by 1.ps1 script, the 2.ps1 script will be able to use...
Now I tried so many ways, First I tried with subprocess but it always creates a new session for every time I enter a command (which is the path of the .ps1 file). Then I found this project at GitHub:
https://gist.github.com/MarkBaggett/a7c10195b2626c78009bf73bcdb6db20
Which is really awesome and did work but still, it seems that when I run the command ./1.ps1 it still does not store the local variables at the session (Maybe it opens a new one when running a script).
I tried to do also "Get-Content 1.ps1 | iex" but then it crashes since I have functions there for example:
function Invoke-Expression()
{
param(
[Parameter( `
Mandatory=$True, `
Valuefrompipeline = $True)]
[String]$Command
)
Write-Host $Command
}
taken from PSDecode project:
https://github.com/R3MRUM/PSDecode/blob/master/PSDecode.psm1#L28
Anyway, any ideas about how I can do this? I have those scripts on my desktop but no idea how to run them at the same session so they will use the same local variables...
Two things that I did though but they really suck:
1. Convert all the scripts to 1 script and run it, but in next run that I will use this program I might have 100 scripts or more and I don't really want to do this.
2. I can save the local variables from each script and load it to another yet I want to use it in the worst case scenario and still didn't get there.
Thank you so much for helping me and sorry for my grammar my English is not my mother language as you can see :)
Maybe you're looking for dot sourcing:
Runs a script in the current scope so that any functions, aliases, and variables that the script creates are added to the current scope.
PowerShell
. c:\scripts\sample.ps1
If so dot-source your ps1 files, and call the functions inside them.
Hope that helps.

Python - run another python script with current environment passing the arguments over and getting the printed print output

A little bit of an ugly question, but I didn't find existing SO posts which cover it.
Right now I need to use an existing python tool available on this github
This is a rather big piece of code with a lot of dependencies which I don't want to mess with. In a nutshell one can run its module by passing the command line arguments, for example:
timesearch.py timesearch -r "subreddit1" -l "1466812800" -up "1498348800"
Now, I need to run this tool a bunch of times using a for loop, passing over different argument values each time. The tool also prints out some output into command line when you run it - and I would like to intercept and print it out from my python script as well. Finally, I need to ensure that before I move on in my loop and run the tool another time that current execution of the timesearch tool is completed.
One side note here - I do need to ensure that the timesearch is executed using same environment which I use to run my main script with for loop.
I am trying to understand what is the best way to do it.
If I just go for this it doesn't work:
import os
#for loop will go here
os.system('python timesearch.py timesearch -r "ethereum" -l "1466812800" -up "1498348800"')
It fails due to several reasons - it doesn't use the environment in which I am writing my script with a loop, it also doesn't capture the print output of timesearch.
Any advice on how to achieve it?
Just to highlight - I can't just go and pull function I need in timesearch, since it calls the __init__ to set up some things based on the arguments you pass.
I wouldn't call python script with os.system. There is basically one function which you need to use: main(sys.argv[1:])
https://github.com/voussoir/timesearch/blob/master/timesearch/__init__.py#L435.

How to execute code from another program as a result of a command

I'm thinking on how to design a program that as a result of all events, checks a command file (which essentially holds key-value pairs where the key is a command and the value is the code to execute) and runs that command's matching code.
It'll be run on a unix/linux machine.
For simplicity's sake, the program will be as follows:
It'll wait for the user's input. When the user inputs a valid command (i.e a command that appears in the commands file), the matching code will be executed. If it doesn't match any command it'll print "No matching command".
So if my command file looks like:
run1='a.py'
run2='b.py'
and I enter "run1" then a.py will be executed. If I enter "run3" then "No matching command" will be printed.
I want to implement this in C++ and I've seen similar implementations where people used system() to execute the commands but this feel like a bad way to achieve this.
What other options do I have to achieve this?
p.s - I wrote in my example that the code being run is in python. I'm not sure I want that to be the only option (so I'll need to be able to identify the type. Lets assume I can do that).
Is this still achievable?
There are LOTS of options. system("a.py"); will do what you want (assuming python is installed correctly on the system you are running on). If that is the "best" solution really depends on what you want to achieve, and that isn't entirely clear from your question.
Most other solutions will be more or less system specific. You could, for example, in Unix/Linux use fork() and one of the flavours of exec() [with python as the actual executable, and "a.py" as the file to run in python], but that won't work in Windows, where you would have to use, for example, spawn() (again with python as the executable file and for example "a.py" as the code to run).

Categories

Resources