Since you mention you solved the problem for your specific situation, below a solution for general purpose. Thanks to xdotool
's --sync
option, it works pretty reliable in the tests I ran; I could "send" commands to specific terminal windows and it ran perfectly without an exception.
How it works in practice
The solution exists from a script, which can be run with two options
-set
and -run
:
To set up (open) an arbitrary number of terminal windows, in this example 3:
target_term -set 3
Three new terminals will open up, their window id is remembered in a hidden file:
For clarity reasons I minimized the terminal window I ran the command from :)
Now that I created three windows, I can send commands to either one of them with the run command (e.g.):
target_term -run 2 echo "Monkey eats banana since it ran out of peanuts"
As shown below, the command ran in the second terminal:
Subsequently, I can send a command to the first terminal:
target_term -run 1 sudo apt-get update
making sudo apt-get update
run in terminal 1:
and so on...
How to set up
The script needs both wmctrl
and xdotool
:
sudo apt-get install wmctrl xdotool
Copy the script below into an empty file, safe it as target_term
(no extension!) in ~/bin
(create the directory ~/bin
if necessary.
Make the script executable (don't forget) and either log out/in or run:
source ~/.profile
Now setup your terminal windows, with the number of required windows as an argument:
target_term -set <number_of_windows>
Now you can "send" commands to either one of your terminals with the command:
target_term -run <terminal_number> <command_to_run>
The script
#!/usr/bin/env python3
import subprocess
import os
import sys
import time
#--- set your terminal below
application = "gnome-terminal"
#---
option = sys.argv[1]
data = os.environ["HOME"]+"/.term_list"
def current_windows():
w_list = subprocess.check_output(["wmctrl", "-lp"]).decode("utf-8")
w_lines = [l for l in w_list.splitlines()]
try:
pid = subprocess.check_output(["pgrep", application]).decode("utf-8").strip()
return [l for l in w_lines if str(pid) in l]
except subprocess.CalledProcessError:
return []
def arr_windows(n):
w_count1 = current_windows()
for requested in range(n):
subprocess.Popen([application])
called = []
while len(called) < n:
time.sleep(1)
w_count2 = current_windows()
add = [w for w in w_count2 if not w in w_count1]
[called.append(w.split()[0]) for w in add if not w in called]
w_count1 = w_count2
return called
def run_intterm(w, command):
subprocess.call(["xdotool", "windowfocus", "--sync", w])
subprocess.call(["xdotool", "type", command+"\n"])
if option == "-set":
open(data, "w").write("")
n = int(sys.argv[2])
new = arr_windows(n)
for w in new:
open(data, "a").write(w+"\n")
elif option == "-run":
t_term = open(data).read().splitlines()[int(sys.argv[2])-1]
command = (" ").join(sys.argv[3:])
run_intterm(t_term, command)
Notes
The script is set for gnome-terminal
, but can be used for any terminal (or other program as well) by changing the application
in the head section of the script:
#--- set your terminal below
application = "gnome-terminal"
#---
- The commands above can (of course) be run from a script as well in case you'd lile to use it for some kind of a simulation.
- The script waits until both the targeted window has focus and the command is done typing, so the command will always land in the right terminal window.
No need to say that the script only works with the terminal setup (windows) that was called by the command:
target_term -set
The terminal windows will then be "labelled" by the script, like you mention in your question.
- In case you start a new
target_term
session, the hidden file, created by the script will simply be overwritten, so there is no need to remove it otherwise.
In a nutshell:
To open a new terminal window with the same full history as the current session, run:
history -a && gnome-terminal
Full explanation:
The Bash history works like this:
- You open a terminal which starts a Bash session.
- Bash loads the old history from
$HISTFILE
, which is usually ~/.bash_history
.
- You can enter commands into the Bash shell. Those commands will be stored in a temporary history in memory.
- You exit the Bash session or close the terminal window.
- Before Bash terminates, it synchronizes the temporary history in memory with the one saved in
$HISTFILE
on the disk.
Note that for both the temporary and the persistent history may have size limits and get truncated when they become too long.
As each Bash instance only writes to a temporary history in your memory, the actions from a running session do not appear if you start a second session in parallel: It will load the old version of the persistent history file!
If you need to synchronize the temporary histories of two Bash instances, you need to do this via the persistent history file. There is a command to help you: history
To flush the current Bash session's temporary history from RAM to the $HISTFILE
on the disk by appending the new command lines to it, you run:
history -a
This command gets automatically invoked whenever you exit a Bash session.
To re-read the $HISTFILE
from the disk and add the new command lines from it to the current Bash session's temporary history which you can use, you run:
history -r
This command gets automatically invoked whenever you start a Bash session.
Note the leading space in front of both history
commands. It prevents that the history
command itself will appear in the Bash history. If you want it to appear there, just omit the space at the beginning.
So to open a new terminal window that has access to all the current history, you need to flush the current temporary history first, and then open a new terminal with a new Bash session:
history -a && gnome-terminal
Again, note the space in the beginning to prevent this command to appear in the histories. If you want it to appear there, omit the space in front of the command.
If you want a short command for that, create a Bash alias:
echo "alias newterminal='history -a && gnome-terminal'" >> .bash_aliases
You could also add a context menu entry to the Gnome-Terminal launcher if you want. Ask for it in a comment if you need it.
To synchronize the histories of two already open terminal windows, first flush the history of the first window, then reload the history file in the second window:
Terminal 1 (source):
history -a
Terminal 2 (target):
history -r
If you need a two-ways synchronisation, first run the history -a
commands on all windows, then run the history -r
everywhere.
More information about the history
command can be found when you execute
help history
Best Answer
If you have for example
/var/log/syslog
,/var/log/auth.log
log files, you can view them both in one terminal by executingtail -f
command .Open terminal and add the following command:
The output: