I was working with Python with a Linux terminal screen. When I typed:
help(somefunction)
It printed the appropriate output, but then my screen was stuck, and at the bottom of the terminal was "(end)".
How do I get unstuck? Thanks in advance.
The standard on GNU (or other Unix-like) systems is to use the environment variable PAGER for the command that should receive output for viewing one screenful ("page") at a time.
Mine is set to:
$ echo $PAGER
less
Yours might be set to more, or a different command, or not set at all in which case a system-wide default command will be used.
It sounds like yours is modelled after the more program. The program is showing you page-by-page output, and in this case telling you you're at the end.
Most of them (basically, any pager more modern than more) allow you to go forward and backward in the output by using the cursor control keys (arrows and PgUp/PgDown), and many other operations besides.
Since you can do all these things wherever you are in the output, the program needs an explicit command from you to know that you're done navigating the output. In all likelihood that command is the keypress q.
For more information on how to drive your pager, e.g. less, read its manpage with the command man less (which, of course, will show pages of output using the pager program :-)
That program uses your pager, which is by default more. You can exit just by pressing q.
Related
This is the Popen code I'm using to open a subprocess (file subprocessShortLaunch.py) in a separate terminal. I've been looking around and I can't find the answer to two questions:
Is there a way to 'name' the terminal window that opens? The terminal window just says 'terminal'.
Is there a way to keep the window open once the process has finished? It seems to automatically close if there is an error of some type.
process = subprocess.Popen(
"gnome-terminal -x python ~/Desktop/subprocessShortLaunch.py",
stdout=subprocess.PIPE,
stderr=None,
shell=True
)
name the window
(1.) You're using gnome-terminal.
If you choose xterm instead,
you could supply a -title foo argument.
(2.) X11 applications support X properties,
manipulated by utilities like xprop.
You can set such properties,
external to gnome-terminal.
In the -title section xterm's man page explains that
X Toolkit sets the WM_NAME property using this value.
(3.) Terminal emulators usually support ANSI
escape codes that were used by DEC's VT-100
terminals. Wikipedia explains this:
Xterm allows the window title to be set by ESC ]0;your favorite window title.
I imagine that gnome also supports ANSI escapes.
Try it and see.
It's just a matter of adding a print()
to your script.
remain open
Is there a way ... ?
Yes, there are many ways,
such as trapping errors and having
an error handler pause so the diagnostics
can be read.
Here is the simplest approach.
You are running subprocessShortLaunch.py.
Create a very short launch.sh script:
#! /usr/bin/env bash
cd ~/Desktop
python ./subprocessShortLaunch.py
echo Please type RETURN
read line
Invoke with
gnome-terminal -x bash ~/Desktop/launch.py
So the Bourne shell will run
the (buggy) python script,
explain that the party's over,
and wait for you to depress the ENTER key.
That gives you time to view any
diagnostic output before you
dismiss the window.
A sleep statement could
be used for similar effect.
As much as I hate regurgitating questions, it's a necessary evil to achieve a result to the next issue I'll present.
Using python3, tkinter and the subprocess package, my goal is to write a control panel to start and stop different terminal windows with a specific set of commands to run applications/sessions of the ROS application stack, including the core.
As such, the code would look like this per executable I wish to control:
class TestProc(object):
def __init__(self):
pass
def start(self):
self.process = subprocess.Popen(["gnome-terminal", "-c", "'cd /path/to/executable/script.sh; ./script.sh'"])
print("Process started.")
def stop(self):
self.process.terminate()
print("Process terminated.")
Currently, it is possible to start a terminal window and the assigned commands/processes, yet two issues persist:
gnome-terminal is set to launch a terminal window, then relieve control to the processes inside; as such, I have no further control once it has started. A possible solution for this is to use xterm yet that poses a slew of other issues. I am required to have variables from the user's .bashrc and/or export
Certain "global commands" eg. cd or roslaunch would be unavailable to the terminal sessions, perhaps due to the order of execution (eg. the commands are run before the bash profile is loaded) preventing any usable terminal at all
Thus, the question rings: How would I be able to start and stop a new terminal window that would run up to two commands/processes in the user environment?
There are a couple approaches you can take, the most flexible here is also the most complicated, so you'd want to consider whether you need to do it.
If you only need to show the output of the script, you can simply pipe the output to a file or to a named pipe. You can then capture that output by reading/tailing the file. This is simplest, as long as the script don't actually need to have any user interaction.
If you really only need to spawn a script that runs in the background, and you need to simulate user interaction but you don't actually need to accept actual user input, you can use expect approach (using the pexpect library).
If you need to actually allow the real user to interact with the program, then you have two approaches. First is that you can embed the VTE widget into your application, this is the most seamless integration as it'll make the terminal look seamless with your application, however it's also the most heavy.
Another approach is to start gnome-terminal as you've done here, this necessarily spawns a new window.
If you need to both script some interaction while also allowing some user input, you can do this by spawning your script in a tmux session. Using tmux send-keys command to automate the moon interactive part, and then spawn a terminal emulator for users to interact with tmux attach. If you need to go back and forth between automated part and interactive part, you can combine this approach with expect.
I have to execute a command and store the output of it in file. The output spans multiple pages and i have to press enter multiple times to see the complete output( similar to that when a man returns multiple pages). I am thinking of using the subprocess module, but how to provide input to the process, when the process prompts.
Disclaimer: I don't know which command you're actually executing so this is just a stab in the dark.
You should not have to provide any input.
Piping the output of the command to cat solves your problem:
less testfile.txt | cat
Also if your goal is to store the output in another file, you can simply to this (this will overwrite):
less testfile.txt > testfilecopy.txt
(and this will append):
less textfile.txt >> logfile.txt
See: https://unix.stackexchange.com/questions/15855/how-to-dump-a-man-page
The best solution is to check if the process does not support a command-line flag to run in "batch mode", disable paging or something similar which will suppress any such "waits". But I guess you have already done that. Given that you have to enter "-help" interactively tells me it's probably no standard unix command which are usually quite easy to run in a sub-process.
Your best bet in that case would be to use expect. There are python bindings available under pexpect.
Expect scripts tend to be fairly ugly, and error-prone. You have to be diligent with error handling. I have only limited practical experience with it as I only modified some of our existing scripts. I have not yet written one myself, but from our existing scripts I know they work, and they work reliably.
I have a python script that runs continuously in background and print some logs on standard output.
If I log with the same user on the same machine via ssh however I cannot see the output since (I guess) I opened a different shell.
Is there any way to specify that the standard output of this process must be seen by all the shell where I am logged with the same username of the one who launched the process?
Alternatively I thought of redirecting the output to a file and open this file… however I would prefer avoiding such a solution.
Thanks in advance for any suggestion…
In UNIX you could write to all shells using the command wall. I'm not sure if there is a Python binding for wall though.
I have seen that indeed screen does what i need...
Thanks Ignacio
I have a python program that displays battery voltages and temperatures in an electric car. I typically run it from a command line on a Mac by simply using the up arrow to find the command to change directory, and then up arrow to find the command to run the program. We figured out how to write a script that does this automatically and saved it as an application. It works great but don't know how to exit the program. I use control C when using the command line. How do I accomplish in in a script or app? I prefer not to ask our customers to use the command line.
import sys; sys.exit()
will stop the Python program. When you call that code is up to you and depends on the details of your program (you could have it happen when a certain button is pressed, or after a certain amount of time, or when other conditions are met). Also be careful if you have to do any "clean-up" before the program ends- this also depends on the type of application.
If for some reason you want to stop it in exactly the same way as hitting Control-C, you could do
raise KeyboardInterrupt