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

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

Related

Execute Command with xterm and close

Im trying to execute a program with xterm and then close xterm with program running but it seems this doesn't work like I would expect it.
In bash there is the option bash -c [command] is there something in xterm too?
Currently im using xterm -e [command] but this keeps the xterm window open till' my program has finished. But I want to open it, run the program, close it and keep the program running.
Is there a way to do it?
I do it (from a bash file) like:
my#self:~$ cat /usr/bin/rdesk.sh
#!/bin/bash
xterm -e 'perl /home/my/script.pl'
when i run the rdesk.sh file it starts xterm with a perl script, giving me some options. after choosing one, I can close the window, running the chosen program.
So you might just have to put your xterm -e ... command into a bash script.

Start detached screen with ssh , without killing after the commands execute [duplicate]

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

Writing a Script to execute commands?

I have never written a script, so bear with me. What I need to do, is make two scripts that I can click on from the desktop, will both open their own terminal (And stay open until I manually close it) and run the given lines.
For the first one, I have to manually run this:
cd home/pi/PiBits/ServoBlaster/user
sudo ./servod
For the second:
cd ~/scratchClient
python crs/scratchClient.py -c servoblaster
How would I do this? I read a few things about putting xterm -e and such in front of it, but none of that works for me...
By the way, this will be used on Raspbian Linux.
EDIT, this worked for me:
Link: ubuntuforums.org/showthread.php?t=1336228 The line that was used: gnome-terminal --execute bash -c "/path/scriptname ; bash"
You just need to add a shebang, which means putting this in the first line of the script:
#!/bin/sh
This causes the bourne shell to be used to interpret the script, this is (probably) the same interpreter that runs when you are in your terminal. Then you should make the script executable chmod +x <script>
Try this.
xterm -hold -e 'cd /home/pi/PiBits/ServoBlaster/user
sudo ./servod' &
and
xterm -hold -e 'cd /home/pi/scratchClient
python crs/scratchClient.py -c servoblaster' &
If it doesn't work, perhaps you should explain in what way this fails. If it works, you can add a shebang in front, save them in files, chmod +x those files, and click away to your heart's content (or perhaps acquire a more sophisticated taste where you simply run these as background jobs without any xterm or other anxious GUI).
Solution was to use gnome-terminal... Found an UbuntuForums post with a similar question such as mine.
gnome-terminal --execute bash -c "/path/scriptname ; bash"

How do I run the same linux command in more than one tab/shell simultaneously?

Is there any tool/command in Linux that I can use to run a command in more than one tab simultaneously? I want to run the same command: ./myprog argument1 argument2 simultaneously in more than one shells (I want to increase this so as to put my code under stress later on) to check if the mutexes are working fine in a threaded program.
I am kind of looking for something like what wall does. I can think of using tty's, but that just seems like a lot of pain if I have to scale this to many more shells.
Why not do something like
for i in {1..100}
do
./myprog argument1 argument2 &
done
This is in case the shell is bash. You can look into other looping constructs in case of other shells.
Running the jobs asynchronously with redirected output is the simplest solution, but if you really want each process to run in its own terminal, a good option is to use a terminal emulator like screen or tmux. For example:
yes | sed 5q | while read k; do # iterate 5 times
tmux new-session -d 'sh -c "/path/to/myprog arg1 arg2; sh"'&
done
The trailing sh causes the session to remain alive after myprog terminates, and the intial yes pipeline is used instead of seq since it works where seq is not available (there are lots of ways to iterate!)
Once the sessions are running, you can attach to them individually to view the output. (See tmux documentation for details.)
if you are using gnome terminal, try this one
gnome-terminal --maximize --tab-with-profile=default -e '/bin/sh -c ./myprog argument1 argument2' --tab-with-profile=default -e '/bin/sh -c ./myprog argument1 argument2' --tab-with-profile=default -e '/bin/sh -c ./myprog argument1 argument2'
please check gnome-terminal man page for more options
Use GNU Parallel's --tmux --fg:
parallel -j20 --tmux --fg echo doit {}\; sleep {} ::: {1..100}
Use ctrl-b n and ctrl-b p to cycle between the running terminals.
That way you can keep everything in a single window, but without the output from the jobs mixing.
Install the moreutulis package (with non-GNU parallel) or, preferably, GNU parallel (often packaged separately; SUSE calls it gnu_parallel, Ubuntu and RedHat call it parallel) so you can use parallel. Then figure out how to specify the terminal your command runs in. For example
parallel yourscript -- tty1 tty2 pts6
Then you just have to figure out how to write "yourscript" to take the tty to run on as an argument, which is a separate question. :)
I had the same situation when I was at college and I did something like this
for i in $(seq 1 10)
do
xterm -e "./myprog argument1 argument2"&
done
This spawns 10 xterms each running your program in the background.
From comments it seems you don't need stdin, do need stdout, don't want ptys, don't want screen or tmux.
Easy-peasy:
for seq in `seq 5`; do
./myprog argument1 argument2 >output$seq &
done
Maybe you could (ab)use clusterssh for that?
Open a bunch of terminals, get everything set up, then hit ENTER really quickly in each terminal.

Avoid gnome-terminal close after script execution?

I created a bash script that opens several gnome-terminals, connect to classroom computers via ssh and run a script.
How can I avoid that the gnome-terminal closes after the script is finished? Note that I also want to be able to enter further commands in the terminal.
Here is an example of my code:
gnome-terminal -e "ssh root#<ip> cd /tmp && ls"
As I understand you want gnome-terminal to open, have it execute some commands, and then drop to the prompt so you can enter some more commands. Gnome-terminal is not designed for this use case, but there are workarounds:
Let gnome-terminal run bash and tell bash to run your commands and then start a new bash
$ gnome-terminal -- bash -c "echo foo; echo bar; exec bash"
or if the commands are in a script
$ gnome-terminal -- bash -c "./scripttorun; exec bash"
The first bash will terminate once all the commands are done. But the last command is a new bash which will then just keep running. And since something is still running gnome-terminal will not close.
Let gnome-terminal run bash with a prepared rcfile which runs your commands
Prepare somercfile:
source ~/.bashrc
echo foo
echo bar
Then run:
$ gnome-terminal -- bash --rcfile somercfile
bash will stay open after running somercfile.
i must admit i do not understand completely why --rcfile has this behaviour but it does.
Let gnome-terminal run a script which runs your commands and then drops to bash
Prepare scripttobash:
#!/bin/sh
echo foo
echo bar
exec bash
Set this file as executable.
Then run:
$ gnome-terminal -- ./scripttobash
for completeness
if you just want to be able read the output of the command and need no interactivity
go to preferences (hamburger button -> preferences)
go to profiles (standard or create a new one)
go to command tab
when command exits -> hold the terminal open
i recommend to create a new profile for just for this use case.
use the profile like this:
gnome-terminal --profile=holdopen -- ./scripttorun
Every method has it's quirks. You must choose, but choose wisely.
I like the first solution. it does not need extra files or profiles. and the command says what it does: run commands then run bash again.
All that said, since you used ssh in your example, you might want to take a look at pssh (parallel ssh). here an article: https://www.cyberciti.biz/cloud-computing/how-to-use-pssh-parallel-ssh-program-on-linux-unix/
Finally this one works for me:
gnome-terminal --working-directory=WORK_DIR -x bash -c "COMMAND; bash"
Stack Overflow answer: the terminal closes when the command run inside it has finished, so you need to write a command that doesn't terminate immediately. For example, to leave the terminal window open until you press Enter in it:
gnome-terminal -e "ssh host 'cd /tmp && ls'; read line"
Super User answer: Create a profile in which the preference “Title and Command/When command exits” is set to “Hold the terminal open”. Invoke gnome-terminal with the --window-with-profile or --tab-with-profile option to specify the terminal name.
Run with -ic instead -i to make terminal close bash proccess when you close your terminal gui:
gnome-terminal -e "bash -ic \"echo foo; echo bar; exec bash\""
As of January 2020, the -e option in gnome-terminal still runs properly but throws out the following warning:
For -e:
# 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.
Based on that information above, I confirmed that you can run the following two commands without receiving any warning messages:
$ gnome-terminal -- "./scripttobash"
$ gnome-terminal -- "./genericscripttobash \"echo foo\" \"echo bar\""
I hope this helps anyone else presently having this issue :)
The ideal solution would be to ask for a user input with echo "Press any key".
But if double-click in Nautis or Nemo and select run in a terminal, it doesn't seem to work.
In case of Ubuntu a shell designed for fast start-up and execution with only standard features is used, named dash I believe.
Because of this the shebang is the very first line to start with to enable proper use of bash features.
Normally this would be: #!/bin/bash or similar.
In Ubuntu I learned this should be: #!/usr/bin/env bash.
Many workarounds exist to keep hold of the screen before the interpreter sees a syntax error in a bash command.
The solution in Ubuntu that worked for me:
#!/usr/bin/env bash
your code
echo Press a key...
read -n1
For a solution applicable to any terminal, there is a script that opens a terminal, runs the command specified and gives you back the prompt in that new terminal:
https://stackoverflow.com/a/60732147/1272994
I really like the bash --rcfile method
I just source ~/.bashrc then add the commands I want to the new startrc.sh
now my automated start.sh work environment is complete... for now 😼
If running a bash script just add gedit afile to the end of the script and that will hold gnome-terminal open. "afile" could be a build log which it was in my case.
Did not try just using gedit alone but, that would properly work too.
Use nohup command.
nohup gnome-terminal -e "ssh root# cd /tmp && ls"
Hope this will help you.

Resources