Run commands in newly opened terminal - python

I want to open a new terminal through python. In that newly spawned terminal I want to execute commands. I've checked multiple posts which are suggested through similar questions but I couldn't find the answer.
I've tried this:
import os
os.system("gnome-terminal -e 'cd /home/john/Documents; echo 'writing to file' > testfile.txt'")
The new terminal spawns but the commands don't get executed in the new terminal.
❯ python3 TestOpenTerminal.py
# Option “-e” is deprecated and might be removed in a later version of gnome-terminal.
# Use “-- ” to terminate the options and put the command line to execute after it.
# Error: Failed to execute child process “cd” (No such file or directory)
How can I do this? Thx

The cd command don't work with gnome-terminal command, you need to use the option --working-directory=/path/to/dir.
The -e option is deprecated, you need to use -- followed by the command, like gnome-terminal -- 'command'.
To manipulate files the only way I could make work is using bash and option -c before the command.
So the command you want to do is:
gnome-terminal --working-directory=/home/john/Documents -- bash -c "echo 'writing to file' > testfile.txt"
I really recommend you to use the fabric library to use with terminal commands, it works with all systems and returns the output to you.

I don't know if you really want to open a terminal, but you could just open the file through python and write with it. Try to use the open() and write() functions.

Look closely at your command. Your opening single quote is closed by the single quotes around 'writing to file' and that causes a mess.
os.system("gnome-terminal -e 'cd /home/john/Documents; echo 'writing to file' > testfile.txt'")
Also, the default behavior of gnome-terminal is to close when complete. You can keep it open by editing the profile as follows...
In gnome-terminal, go to Edit -> Profile Preferences -> Title. Click the Command tab. Select Hold the terminal from the drop-down menu labelled When command exits. You should create a new profile for that and execute with
gnome-terminal --window-with-profile=NAMEOFTHEPROFILE -e command

Related

How could I use python to open gnome-terminal and then run python commands in a multiline manner?

I am attempting to get a subprocess call that will open a gnome-terminal and in that terminal enter python then execute some python commands and imports without the user needing to type them out.
I'm working on on some automated terminal opening code that will open a gnome-terminal window using subprocess.call (Open new gnome-terminal and run command) also (Python syntax to open gnome-terminal and execute multiple commands)
My end goal is to open up a gnome-terminal window and with the same script that opened the gnome-terminal, enter the command to use python. And then in python import a package and run it.
My current usage is:
subprocess.call(['gnome-terminal', '-e', "python client.py"])
However what Im trying to get to is an importable package that I can open several gnome terminal windows for that will call different objects from a pypi package effectively doing the same thing that call client.py would do with the files. This doesnt work with packages installed in pip however.
What I want to do is something along the lines of:
subprocess.call(['gnome-terminal', '-e', "python && import <package> && c = <package>.obj.func()"])
So that a terminal would open and enter python, import the package I want, then call something from it, but all as instructed by a python file
This doesnt appear to work as multiline scripting works for stuff like bash scripting but doesnt seem to work when trying to enter commands after python has been entered.
Any advice would be greatly appreciated
I don't have Gnome Terminal installed, but if you can get that to start Python correctly, then you can use Python's -i flag to run a set of commands or a script.
The two usages are as follows:
python -i path/to/my/script run the script then enter the interpreter
python -i -c "# Some Python commands" run the command(s) then enter the interpreter
For example:
$ python -i -c "import this"
[poetry]
>>>
# Ready for input!

How to open a 2nd terminal from 1st one and run command in it? (without it being child process)

I am trying to write a script in python which should change my desktop wallpaper on my raspberry pi. I am a beginner in both python and linux, have been stuck on this problem the whole day. Would love to hear from you guys <3
This is the terminal command which changes my desktop wallpaper:
pcmanfm --set-wallpaper /usr/share/rpd-wallpaper/wallpaper.jpg
Concerning only the linux terminal syntax: i would like to open a second terminal and run a command in it, all initiated from the first terminal. If i type into my first terminal:
pi#raspberrypi:~ $ lxterminal &
it opens a new terminal window which stays open, and is not a child process right? In this 2nd terminal my change wallpaper command works. The following command does not work and if i put a "&" next to gnome-terminal it opens a new terminal but does not execute the command that was specified with -e and gives me an error.
gnome-terminal -e 'bash -c \"pcmanfm --set-wallpaper /usr/share/rpd-wallpaper/wallpaper.jpg; exec bash\"'
How do you open a new terminal with a command passed with -e which is also not a child process?
I know you are new so I want to introduce some concepts to you before I can answer your question.
The "&" operator in shell/unix is not meant to open a new terminal. It is an operator that invokes unix's handy little job control protocol, which allows the parallelization of complex programs! It's awesome. It makes that command a background process, which basically means it starts a new shell (or "terminal" in the language of your OP) which runs that process and leaves you in control of your current shell (or terminal). The shell you are still in control of is called the foreground process.
now, what you have going on with gnome-terminal is a little more complicated. gnome-terminal is executing a bash terminal (which has a shell for each process you run inside it) in the GNOME environment. -e is the command you want to send to this terminal. So, you put the ampersand (&) at the end of that command if that is the command you desire to send to the background.
Now, let's look at the command you want to run:
gnome-terminal -e 'bash -c \"pcmanfm --set-wallpaper /usr/share/rpd-wallpaper/wallpaper.jpg; exec bash\"'
-e indicates the command you want to run in the new terminal. bash-c (commmand) is changing your wallpaper. Ok, cool. exec bash is probably any weird error thrown, if I had to guess. But that line should perform nothing at all.
What it sounds like to me is you don't really need to send anything to the background.
gnome-terminal -e 'bash -c \"pcmanfm --set-wallpaper /usr/share/rpd-wallpaper/wallpaper.jpg
should change your wallpaper. But, to answer the question completely, just place the & AFTER whichever command you wish to send in the background.

Bash script: Open Python, execute some lines, then let user take control

I have a Python program, A.py, that creates binary data upon completion. To help users analyze the output, I want to add a small script, B.sh, to the output directory that fires up a Python console and executes some commands, C, that load the data and prepare them such that a user sees what is available. After executing C, the script B.sh should keep the Python console open.
First attempt at B.sh:
I figured out that
#!/bin/sh
xterm -e python
opens a Python console and keeps it open but doesn't execute anything within that console.
Second attempt at B.sh:
I figured out that
#!/bin/sh
xterm -e python -i C.py
executes C.py (I'd prefer not to have to write an additional file for the startup commands, but I could live with that) and keeps the window open, but doesn't show what was done. More specifically, the user would be presented with the outputs of C, but not the command that were used to achieve the outputs.
Instead,I'd like the user to be presented with a console like this:
>>> [info,results] = my_package.load(<tag>)
>>> my_package.plot(results)
>>> print(info)
<output>
>>> my_package.analyze(results)
<output>
>>>
Save this in a file called demo.tcl
#!/usr/local/bin/expect -f
# Spawn Python and await prompt
spawn /usr/local/bin/python3
expect ">>>"
# Send Python statement and await prompt
send "print('Hello world!')\n"
expect ">>>"
# Pass control to user so he can interact with Python
interact
Then make it executable with:
chmod +x demo.tcl
And run with:
xterm -e ./demo.tcl
In the picture, you can see I went on after the "Hello world" to print the system version info.
Your paths for Python and expect may be different, so check and alter to suit.
For anyone who happens to be using macOS (a.k.a. OSX), you can install expect with homebrew as follows:
brew install expect
And, since Macs don't ship with X11 any more, rather than install XQuartz and run xterm, you can start a new Terminal and run the Python in there quite simply with:
open -a Terminal.app demo.tcl
As suggested by user #pask I simply printed the commands before executing them.
Furthermore, I added a -c switch to be able to put the Python commands directly in B.sh instead of having to write a file C.py
Here is the B.sh I am using now:
#!/bin/sh
xterm -e python -i -c "print('>>> import my_package');import my_package;print('>>> [info,results] = my_package.load()');[info,results] = my_package.load()"

Keep terminal open when running Python GUI application from bash script

This is probably a very simple question, but I just can't figure it out. I've coded a Python GUI application (uses PyQT), and all I want to do is to launch it with an executable script. I'm still debugging the application, so it'd be nice if the terminal stays open to see any errors/print statements/exceptions thrown.
This is what I've got in my script:
#!/bin/sh
x-terminal-emulator -e cd dirname && python GUIapp.py
It successfully runs the Python application, but once the application loads, the terminal automatically closes. The application continues to run after the terminal closes.
I know I can open a terminal and then simply type in "cd dirname && python GUIapp.py", but I'm lazy.
What am I missing here?
Use --hold or --noclose option. They have the same function with different name.
So change script to
#!/bin/sh
x-terminal-emulator --noclose -e cd dirname && python GUIapp.py
If you are looking for a command option, always check --help. In this case it gives you the needed information.
user#host:~/projects$ x-terminal-emulator --help
Usage: x-terminal-emulator [Qt-options] [KDE-options] [options] [args]
Terminal emulator
Generic options:
[...]
Options:
[...]
--hold, --noclose Do not close the initial session automatically when it ends.
[...]

How to start a Python ipython shell, automatically run inside it a few commands, and leave it open?

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

Categories