I am using Ubuntu 12.04 and Octave:
$ octave
octave:1> _
I set my editor to gedit:
octave:1> edit editor "gedit %s"
I edit a function:
octave:2> edit someFunction
gedit opens someFunction.m as expected and prompt returns while gedit still has the file open:
octave:3> _
I run some other long-running function:
octave:3> runAllTests
While runAllTests is executing I press CTRL-C to interrupt it.
The observed behavior is that runAllTests is interrupted AND gedit is killed.
The expected behavior is that runAllTests is interrupted AND gedit is NOT killed.
Does anyone know how to stop CTRL-C from killing gedit in this circumstance? Alternatively is there another way to interrupt runAllTests without killing gedit?
The setting:
edit editor "gedit %s &"
causes octave to place the editor "in the background", so CTRL-C does not effect it and has the expected behaviour.
Try:
edit mode async
which specifies asynchronous mode of execution of the edit command
The problem is CTRL+C is also a copy command. IT may need to be customized as in Octave GUI Xoctave. They claim that customization is available.
Unfortunately, putting the forked process in background with '&' is not enough when working with the command line (octave-cli).
There is a bug open on the GNU Octave development webpage about this issue.
Of course it is not only an editor problem, but any new forked process is affected. For instance
octave> system("$TERM&")
creates a terminal in a new window, which would be killed by subsequent <ctrl-c>.
I propose a shell-based workaround. This consists in adding an additional layer of "forking in background", which would protect the final terminal (or text editor or whatever) from the signals sent to octave. In brief, I launch a terminal which launches another terminal in background, from which I kill the first terminal (so that it does not bother us).
Create an executable:
term-kill.sh
-----------------------------
#!/bin/sh
$TERM&
sleep 0.01
kill $1
-----------------------------
(note the sleep commands without which the second terminal does not have time to get detached from the first before the latter gets killed). Then, the command
octave> system("$TERM -e term-kill.sh $$&")
creates a single terminal which won't get killed.
To open a text editor, simply consider the executable
term-edit-kill.sh
------------------------
#!/bin/sh
$TERM -e $EDITOR $1&
sleep 0.01
kill $2
------------------------
and change the octave edit command through
octave> EDITOR('$TERM -e term-edit-kill.sh %s $$')
N.B.: I assumed that your system knows how to find term-kill.sh and term-edit-kill.sh, and that the variables $TERM and $EDITOR exist and suit your needs. The terminal emulator must support the -e option.
Related
I am trying to write a bash script to automate running some commands. However some of these commands should be running in their own terminal tab.
So I use the following in my bash script to open a new tab:
xdotool key ctrl+shift+t
this does the job, but the next commands in my bash script are still executed in the previous terminal tab.
How can I make the new opened terminal tab active and run the next commands in this tab?
What Terminal Emulator are you using? It strongly depends on this.
In general, you could write the commands you want to execute in a shell script and tell your terminal emulator to execute the script once it has started.
Example with xterm:
echo '#!/bin/bash' > /tmp/thescript
echo 'ls -la' >> /tmp/thescript
chmod +x /tmp/thescript
xterm -hold -e /tmp/thescript
EDIT: I just saw that u asked for a way to achieve this with xdotool. So this answer might be invalid. Please tell me if so - then i'll delete it.
How are you using xdotool? It can be done with a chain, for example:
$ xdotool key "ctrl+shift+t"; xdotool type "ls"; xdotool key Return
If all you want is to run the commands in the background / in parallel, without synchronously waiting for each command to complete before the next begins, terminate them with an ampersand & to instruct the shell to do so.
Alternatively, you can execute the commands in their own subshells by surrounding each with parentheses ( ). If they are long running processes or you do not wish to pollute the original shell with their output, you can fork them off and capture their output to file with something like (setsid command 1>/path/to/log &).
If separate tabs is necessary requirement, you can use xdotool to key the switch-to-the-next-tab binding or similar, and then key the commands you must run in that tab.
Instead of sorting out that mess yourself, you could use a script from this answer by Jacob Vlijm, which wraps a windowed approach that uses xdotool and wmctrl to 'send' commands to different terminal windows. The script is written in python 3 but it can easily be rewritten for a shell environment of choice.
A more direct approach involves use of a TIOCSTI ioctl to inject characters into another terminal. According to the tty_ioctl manual page:
NAME
ioctl_tty - ioctls for terminals and serial lines
...
DESCRIPTION
The ioctl(2) call for terminals and serial ports accepts many possible
command arguments.
...
Faking input
TIOCSTI const char *argp
Insert the given byte in the input queue
...
Here are c and perl wrappers, and an example in python as referenced by this answer.
I need an example of gnome-terminal command to read lines of text from a file and executes them one by one in different terminal or a tab.
So this would be the process. I would run gnome terminal command and it would read 10 commands from a file. Then it would execute those 10 commands in 10 different tabs/terminals. And of course those tabs/terminals would remain opened. I found this question Avoid gnome-terminal close after script execution?
The third answer from the top is very helpful. I managed to open 1 command from a file. But I need 1 file with 10 command lines to be opened like I wrote above.
Thanks.
I recommend to use screen for this, if that can be acceptable to you.
You could create a commands.screenrc file like this:
screen bash -c 'command1; echo press any key; read'
screen bash -c 'command2; bash'
screen mutt
screen emacs
screen
You can define as many programs as you want. Start screen with:
screen -c commands.screenrc
I don't know what kind of commands you want to run. If you want to see their output, then write like the first example above: execute the command in a bash shell, which will "pause" after the command was executed. Or the second line, which, after running the command will start another bash shell. Otherwise the screen window would exit automatically.
If you are not familiar with screen, you will need to learn some basic key strokes to get around, and to be able to switch between windows. The first few pages of this presentation should be enough to get you started.
I'm working with a tool right now that requires me to putty to a remote host, login, run a series of commands to start an engine, open a new window (and login again) to start a different engine, then open a third window (and again, login) to actually use the tool (leaving the engines running in those first two windows). I'd like to write a shell script to automate the process so that I could just open one window, type "sh whatever.sh" and be off and running, without physically opening the new windows and logging in again. However, I can't find a command to get me from one window to the next. Any thoughts?
You can just background the first processes by adding an ampersand (&) to the command line or pressing Ctrl+Z when it is running (and then enter bg to let the process continue, more information about that with jobs).
If that's not enough, you can create virtual shells with screen or tmux.
If you've redirected X (i.e. you can access GUIs over ssh), you can also just start a new window by executing your favorite (GUI) console program, like xterm, konsole, gnome-terminal, etc.
Are you familiar with jobs on linux?
nohup whatever_1.sh &
nohup whatever_2.sh &
nohup whatever_3.sh &
Or perhaps screen would be of use here:
https://serverfault.com/questions/25301/job-control-and-ssh
See also, nohup:
http://en.wikipedia.org/wiki/Nohup
The bash command opens a Bourne-again shell (bash) session.
Try typing in "konsole". That should open a new bash window and set the focus to it.
On my Ubuntu 18 I just type the command:
gnome-terminal
and a new shell opens... I don't like the above answers because xterm and konsole most likely not already be installed.
Shell script on target machine cannot be aware of putty windows on client machine.
Consider using Screen : http://www.gnu.org/s/screen/ - it is clean and powerful way.
I think you need command line window then write:
$ xterm
# new window started
If you need python in new window:
$xterm python
#now a window will shown with python shell
Another nice option from Xfce's terminal:
xfce4-terminal
Is there a way to shutdown Eclipse cleanly from the command line, such that files and workspaces are saved? kill -3 doesn't do anything. kill -1 and kill -15 (default) causes Eclipse to exit abruptly with JVM termination popup. kill -9 does the same thing.
The use case is that I'm working remotely on a machine with Eclipse loaded on it, and I want to save memory by closing Eclipse, but I want Eclipse to save its state first.
I could use VNC or some alternative desktop sharing software, but that's really heavy-weight, and I'd much prefer a command line solution.
EDIT: System info: RHEL5.1 64-bit using GNOME
I figured this out with the help of gigi's answer and another question. You're going to need the wmctrl and xdotool utilities from your package manager.
Unless you're running in a terminal emulator on the same display, you need to set the right display:
$ export DISPLAY=:0.0
Then (irrelevant windows elided from example):
# List windows
$ wmctrl -l
...
0x030000fa 0 kcirb Java - Eclipse
# Tell Eclipse window to close gracefully
$ wmctrl -c eclipse
# Darn, there's a confirmation dialog
$ wmctrl -l
...
0x030000fa 0 kcirb Java - Eclipse
0x03003c2d 0 kcirb Confirm Exit
# Send return key to the window
$ xdotool key --window 0x03003c2d Return
Worked for me on Ubuntu 12.04, at least.
EDIT: See Scarabeetle's answer for the tweaks you need to make it work from a script.
Not enough reputation to comment on pidge's answer above...
It almost works, but I needed to wait for some Gnome3 animation to finish and then give focus to the "Confirm Exit" window:
export DISPLAY=:0.0 # Do this in main X session
wmctrl -c "Eclipse SDK" # Close main window
sleep 1 # Wait for animation
wmctrl -a "Confirm Exit" # Give focus to the dialog
# Send a Return keypress to press the OK button
xdotool key --window $(xdotool search "Confirm Exit") Return
Any added ShutdownHooks (more info here) should be executed by the JVM when terminated by SIGTERM. Therefore, I think the problem is the way Eclipse is programmed to deal with such signals.
As I don't know how the cleanup process is implemented in Eclipse, I can only assume that it is not called by any ShutdownHook (and rather by an Action or something similar).
Edit: pidge has provided an answer below however which details steps which should allow you to shutdown Eclipse cleanly from the command line.
Try killing java process(es). Do ps -ea | grep java
Did you tried with wmctrl?
wmtrl -l
lists the windows and
wmlctrl -c -P
should close the window.
Anyway you could have problems with the confirmation dialog of eclipse.
Did you try kill -HUP (kill -1)? -- that's the canonical way to tell a process that whoever was interacting with it has gone away and it should clean up appropriately
The answer to this question was helpful to me in a similar issue: Eclipse hanging, how to kill it properly?
After I killed the eclipse process the Eclipse window kept there until I killed the java process (I didn't have a javaw process as in the answer above. I had only one "java" process that when killed fixed the problem).
I've got a program running in a GNOME Terminal, but the screensaver is acting up and won't let me back in with my password. While waiting for a fix for the gnome-screensaver bug, is there some way to see the output (or even take over the process) in a virtual console (Ctrl-Alt-F1) without being able to interact with the GNOME Terminal?
Clarification: The original issue was the screensaver, but the question I'd like answered is how to see the output from a process running in another terminal, after starting the process without any logging to file. I'm guessing it should be possible to set the output device of a process from a different shell? Or is it possible to put a process in another shell into background mode, and get it into the foreground in the current shell? Or even ask GNOME Terminal to redirect or copy the output?
I've had luck in the past killing the screensaver from a virtual console, unlocking X session.
# Get the pid (xscreensaver, gnome-screensaver, etc.)
ps -f -u $(whoami) | grep screensaver
kill -9 12345 # Replace 12345 with the real pid
EDIT: Seems like this has been thought of, and you should use one of these commands, depending on which screensaver program you use:
xscreensaver-command -exit
gnome-screensaver-comand --exit
See the man page for those commands for more details.
Usual way is to pipe the output to a file, like program > program.log
Do tail -f program.log in another tab of Gnome console, and the same in the non-X console.
Alternatively, use tee to duplicate the output in the same console: program | tee program.log
ssh in to the box. kill the screensaver. su to become root and kill -9 if it's really acting up.
Usually Gnome-Terminal displays the output of one vty out of /dev. So just connect your console to that vty.
Launch program with screen.
Open another terminal, launch screen -x and you have two terminals acting like one. Try it, it's fun :)