Obviously it helps to have the interpreter to debug, but I prefer to execute commands in terminal. Is there any way to make it run the python program, then startup an interpreter with the variables and functions created already in there. My current command is this:
python main.py < tests/1.in
Does anyone know how to modify it to make the variables and functions accessible after runtime?
Use the -i flag:
python -i main.py < tests/1.in
Houw about -i:
-i : inspect interactively after running script; forces a prompt even
if stdin does not appear to be a terminal; also PYTHONINSPECT=x
Related
I would like to run a Python script setting in the shell where the interpreter must look for the modules.
Suppose that myscript.py contains only:
import mymodule ; mymodule.myfunction()
But mymodule is in /home/user/hello, whereas myscript.py is, say, in /home/user/Desktop. I want to run on a terminal something like:
$ python /home/user/Desktop/myscript.py LOCATION_OF_THE_MODULES=/home/user/hello.
Would it be possible? I think that an alternative solution is to define the location in the import statement from the code, but this is not what I am looking for. I want to set the location through a variable in the shell.
So, I've been exploring a little your question, turns out this isn't a Python question but a "prompt" question, because indeed there is a way to do that but, since Python can't hop into interactive from script, we can't make it using Python only, but the Python interactive command have some extra options we can use
see:
python3 -h
for more info.
Specifically there are 2 options that are interesting, -i and -c which stands for interactive mode and command string respectively, that way we can load the modules with -c and hop into interactive with -i, like so:
python3 -i -c "import os"
Obviously, we need to make it more advanced so it can load multiple modules without Python scripting, then we will be needing to make the actual command to run Python and load the scripts you want, there is a problem tho, since we need to issue a command to be able to load all the modules you want in a folder it might create incompatibilities with prompts since not all prompts have the same syntax. There might be another low-level answer to this problem but I couldn't get to it, however, I will leave a Bash Script for reference so you can use it and/or edit it so it works best with your prompt.
FINAL_VAR=""
cd $1
for f in *.py; do
FINAL_VAR+="import ${f%.py}"$'\n'
done
python3 -i -c "$FINAL_VAR"
Usage steps:
Copy and save the script
Give it run permissions (chmod +x file_name.sh)
Run it this way: ./file_name.sh "/full/path/to/your/modules"
It will load all the .py files and will hop into an interactive Python shell for your use
Note: You might want to change the last line so it works accordingly to your Python installation
I am trying to created aliases for tcsh from a python script (running Python 2.7.1).
Once the aliases are created I want to use them in the same shell I ran the python script in.
I tried:
os.system('alias test "echo test"')
but I get the following error:
sh: line 0: alias: test: not found
sh: line 0: alias: echo test: not found
I then tried:
os.system(r"""/bin/csh -i -c 'alias test "echo test"'""")
And then no errors occurred, but the alias did not register, and therefore I could not use it.
The result I'm looking for is this:
tcsh>python my_script.py
tcsh>test
test
Thanks!
os.system executes that command in a subshell (the bourne shell by the look of it), so even if your syntax was correct alias test="echo test", it would not persist after the call (since the subshell closed).
But this seems like an XY question. You ask about Y - the solution you had in mind, and not about X - your problem.
If you simply want to create a bunch of aliases at once, why not use a c-shell script!? (Why you are torturing yourself with c-shell is another matter entirely).
Your python script cannot execute anything in the context of your shell. While you could use subprocess.call(..., shell=True) this would use a new shell and thus not update your existing shell.
The only way to do what you want is to make your python script write valid shell commands to stdout and then, instead of just executing it, you need to make your shell evaluate the output of your python script.
I'm working on windows vista, but I'm running python from DOS command. I have this simple python program. (It's actually one py file named test.py)
import os
os.system('cd ..')
When I execute "python test.py" from a Dos command, it doesn't work.
For example, if the prompt Dos Command before execution was this:
C:\Directory>
After execution, must be this:
C:\>
Help Plz.
First, you generally don't want to use os.system - take a look at the subprocess module instead. But, that won't solve your immediate problem (just some you might have down the track) - the actual reason cd won't work is because it changes the working directory of the subprocess, and doesn't affect the process Python is running in - to do that, use os.chdir.
I don't really use Windows, but you can try cmd /k yourcommandhere. This executes the command and then returns to the CMD prompt.
So for example, maybe you can do what you want like this:
subprocess.call(['cmd', '/k', 'cd .. && prompt changed'])
As I said, I am not familiar with Windows, so the syntax could be wrong, but you should get the idea.
In case you don't know, this is a different CMD instance than the one you were in before you started your python script. So when you exit, your python script should continue execution, and after it's done, you'll be back to your original CMD.
I tried
echo "print 'hello'" | ipython
Which runs the command but ipython immediately exits afterwards.
Any ideas? Thanks!
Edit:
I actually need to pass the command into the interactive Django shell, e.g.:
echo "print 'hello'" | python manage.py shell
so the -i switch gimel suggested doesn't seem to work (the shell still exits after execution)
Use the same flag used by the standard interpreter, -i.
-i
When a script is passed as first argument or the -c option is used, enter interactive mode after executing the script or the command, even when sys.stdin does not appear to be a terminal. The PYTHONSTARTUP file is not read.
A Linux example, using the -c command line flag:
$ ipython -i -c 'print "hello, ipython!"'
hello, ipython!
In [2]: print "right here"
right here
In [3]:
Try using the ipy_user_conf.py inside your ~/.ipython
I'm not sure of ipython but the basic python interpreter has a command line parameter to give you the prompt after it executes the file you've given it. I don't have an interpreter handy to tell you what it is but you can get it using python --help. It should do exactly what you want.
Running a custom startup script/profile script with the Django shell was marked as closed: wontfix.
However, there is a shell_plus Django extension discussed in that ticket which seems to do what you want. I haven't had a chance to check it out, but it looks like at the very least it can run a load to auto import all the models of all installed apps (which I usu. find myself doing).
Shell plus.py in django-command-extensions on Google Code
django-command-extensions homepage on Google Code
django_extensions on Github
I am writing a python script (Linux) that is adding some shell aliases (writes them to HOME/.bash_aliases).
In order to make an alias available immediately after it was written I should issue the following bash built-in:
source HOME/.bashrc
source is a bash built-in so I cannot just:
os.system(source HOME/.bashrc)
If i try something like:
os.system('/bin/bash -c source HOME/.bashrc')
...will freeze the script (just like is waiting for something).
Any suggestions ?
What you want is not possible. A program (your script) cannot modify the environment of the caller (the shell you run it from).
Another approach which would allow you to do something close is to write it in terms of a bash function, which is run in the same process and can modify the caller. Note that sourcing during runtime can have possible negative side-effects depending on what the user has in their bashrc.
what you are trying to do is impossible. or better: how you are trying to do it is impossible.
your bash command is wrong. bash -s command does not execute command. it just stores the string "command" in the variable $1 and then drops you to the prompt. that is why the python script seems to freeze. what you meant to do is bash -c command.
why do you source .bashrc? would it not be enough to just source .bash_aliases?
even if you got your bash command right, the changes will only take effect in the bash session started from python. once that bash session is closed, and your python script is done, you are back at your original bash session. all changes in the bash session started from python is lost.
everytime you want to change something in the current bash session, you have to do it from inside the current bash session. most of the commands you run from bash (system commands, python scripts, even bash scripts) will spawn another process, and everything you do in that other process will not affect your first bash session.
source is a bash builtin which allows you to execute commands inside the currently running bash session, instead of spawning another process and running the commands there. defining a bash function is another way to execute commands inside the currently running bash session.
see this answer for more information about sourcing and executing.
what you can do to achieve what you want
modify your python script to just do the changes necessary to .bash_aliases.
prepare a bash script to run your python script and then source .bash_aliases.
#i am a bash script, but you have to source me, do not execute me.
modify_bash_aliases.py "$#"
source ~/.bash_aliases
add an alias to your .bashrc to source that script
alias add_alias='source modify_bash_aliases.sh'
now when you type add_alias some_alias in your bash prompt it will be replaced with source modify_bash_aliases.sh and then executed. since source is a bash builtin, the commands inside the script will be executed inside the currently running bash session. the python script will still run in another process, but the subsequent source command will run inside your currently running bash session.
another way
modify your python script to just do the changes necessary to .bash_aliases.
prepare a bash function to run your python script and then source .bash_aliases.
add_alias() {
modify_bash_aliases.py "$#"
source ~/.bash_aliases
}
now you can call the function like this: add_alias some_alias
I had an interesting issue where I needed to source an RC file to get the correct output in my python script.
I eventually used this inside my function to bring over the same variables from the bash file I needed to source. Be sure to have os imported.
with open('overcloudrc') as data:
lines = data.readlines()
for line in lines:
var = line.split(' ')[1].split('=')[0].strip()
val = line.split(' ')[1].split('=')[1].strip()
os.environ[var] = val
Working solution from Can I use an alias to execute a program from a python script :
import subprocess
sp = subprocess.Popen(["/bin/bash", "-i", "-c", "nuke -x scriptpath"])
sp.communicate()