How to use xdotool to open a new tab, switch to it and run commands in it - linux

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.

Related

I want to run some commands in the same shell script on different tabs/terminal [duplicate]

This question already has answers here:
How to open a new tab in GNOME Terminal from command line? [closed]
(10 answers)
Closed 3 years ago.
I actually want to run some commands of the same script on different tabs or terminal because these commands are activating servers and listening to different ports. So they have to be always active. As well, I want to have a reference to the tab or the terminal so that I can later shut them down at the end of the script. Help please.
I tried a simple script test to see if I could find a way for opening other tabs :
tab=" --tab"
options=()
cmds[1]="echo Banana"
cmds[2]="echo Cat"
for i in 1 2; do
options+=($tab -e "bash -c \"${cmds[i]} ; bash\"" )
done
gnome-terminal "${options[#]}"
exit 0
but I get this as a result :
./test.sh
# 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.
# 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.
Is there any way to open tabs ? and get a reference to each one so that I can shut down commands related to servers once the treatment is done ?
You could use a programm called tmux. It's a terminal-multiplexer, like screen. With that you can open different sessions and windows (these are like tabs) in the same terminal window. They can be referenced by name or id via script.
It's very probable, that the package manager of your Linux distribution has tmux.
P.S: I have to post an answer instead of a comment as I don't have enough reputation for commenting.
This is what I found for man gnome-terminal ; I think that could help , thanks
gnome-terminal(1) General Commands Manual gnome-terminal(1)
NAME
gnome-terminal — is a terminal emulation application.
SYNOPSIS
gnome-terminal [-e, --command=STRING] [-x, --execute ] [--window-
with-profile=PROFILENAME] [--tab-with-profile=PROFILENAME] [--window-
with-profile-internal-id=PROFILEID] [--tab-with-profile-internal-
id=PROFILEID] [--role=ROLE] [--show-menubar] [--hide-menubar]
[--geometry=GEOMETRY] [--working-directory=DIRNAME] [-?, --help]
DESCRIPTION
GNOME Terminal is a terminal emulation application that you can use to
perform the following actions:
Access a UNIX shell in the GNOME environment.
A shell is a program that interprets and executes the commands that you
type at a command line prompt. When you start GNOME Terminal, the
application starts the default shell that is specified in your system
account. You can switch to a different shell at any time.
OPTIONS
-e, --command=STRING
Execute the argument to this option inside the terminal.
-x, --execute
Execute the remainder of the command line inside the termi‐
nal.
--window-with-profile=PROFILENAME
Open a new window containing a tab with the given profile.
More than one of these options can be provided.
--tab-with-profile=PROFILENAME
Open a tab in the window with the given profile. More than
one of these options can be provided, to open several tabs .
--window-with-profile-internal-id=PROFILEID
Open a new window containing a tab with the given profile ID.
Used internally to save sessions.

How can I launch multiple xterm windows and run a command on each, leaving each window open afterward?

I'm lazy, and I prefer that computers do my work for me. I ssh into several machines on a daily basis, so I created a simple script that launches some xterm windows and places them in positions I want (as you can see, I'm using bash):
#!/bin/bash
xterm -geometry 80x27+1930+0 &
xterm -geometry 80x27+2753+0 &
xterm -geometry 80x27+1930+626 &
xterm -geometry 80x27+2753+626 &
However, the next thing I do is go to the first window and type in
ssh server_a
then in the second
ssh server_b
and so on. What I'd like to do is have my script do the ssh commands in each xterm window, and then leave the windows open for me to do my work. I've seen the -e option for xterm, but the window closes after I execute my command. Is there a way to do this?
I apologize if this is a duplicate question. I've searched around and haven't had any luck with this. Many thanks!
I'd love to see a more elegant answer, but what I came up with does work:
xterm -e bash -c 'echo foo; exec bash'
Replace echo foo with the command of your choice, and you're good to go.
This answer gives one of the best answers I've seen so far to do this. Use the bash --init-file flag either in the shebang or when executing the terminal:
#!/bin/bash --init-file
commands to run
... and execute it as:
xterm -e /path/to/script
# or
gnome-terminal -e /path/to/script
# or
the-terminal -e bash --init-file /path/to/script/with/no/shebang
My only real complaint with the exec option is if the command executed prior to exec bash is long running and the user interrupts it (^C), it doesn't run the shell. With the --init-file option the shell continues running.
Another option is cmdtool from the OpenWin project:
/usr/openwin/bin/cmdtool -I 'commands; here'
# or
/usr/openwin/bin/cmdtool -I 'commands; here' /bin/bash
... where cmdtool injects the commands passed with -I to the slave process as though it was typed by the user. This has the effect of leaving the executed commands in the shell history.
Another option is to use gnome terminator. This creates and positions terminals interactively, and you can set up each terminal to run commands within terminator preferences.
Also does lots of extra tricks using keybindings for things like move, rotate, maximise/minimise of terminals within the containing terminator window
See: https://superuser.com/a/610048
"ClusterSSH controls a number of xterm windows via a single graphical console window to allow commands to be interactively run on multiple servers over an ssh connection"
https://github.com/duncs/clusterssh/wiki
$ cssh server_a server_b
$ command

gnome-terminal executes commands from file

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.

How do I open a new window (shell) from command line in Linux?

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

TCL - open a new terminal, do some operations in the opened terminal and close it

How can I open a new terminal from TCL code, do some operations (e.g. ls -l), get the results of those operations and close that terminal?
Does the exec command open a new terminal and all the operations are invoked in the terminal or when I call for example "cd .." with exec, that command has nothing to do with the linux terminal and linux commands, those are just pure tcl commands that have the same name as linux standard commands?
Sounds like you want Expect.
Any command you pass to exec will be sent to the system to be executed. exec does not open a terminal window to do this: it does not need to open a GUI window like a terminal just to interact with the underlying system.
A couple of specific notes about your example commands:
parsing the output of ls or ls -l is not recommended. Suppose you have an odd but valid filename like "foo\nbar". You're better off iterating over the results of Tcl's glob command.
cd happens to be a Tcl command.
I have done my task with this:
set cvsUpdStr [exec $pathToCvsInYourSystem -qn upd]
It does not open a terminal, but it does the task:
executes a command
results is being stored in cvsUpdStr and can be used later
Also it is possible to use it with catch to understand if it was executed correctly or to avoid errors:
if {[catch {exec $pathToCvsInYourSystem -qn upd} result]} {puts $result}

Resources