Multiple tabs and Bash scripting - bash

I am trying to open multiple tabs and execute a series of commands in each tab. Lets say I open 3 tabs tab1, tab2, tab3. Then in each tab I would like to execute following:
ssh user#address (PublicKey Authentication is setup and
hence no need to enter password)
Launch python scripts (python some.py)
Hold the tab open after executing the commands to see the outputs.
I went through some threads and have a rough outline for Bash script.
#!/bin/bash
echo "Script running"
gnome-terminal -e "bash -c \"ssh user#address; uname -a; exec bash\""
When I run the above script, a new terminal opens and I can see that I have ssh-ed into the target address but the other command uname -a didnot execute.
I would like to build upon this to implement the following:
Open multiple tabs and run commands. Ex : gnome-terminal --tab -e
"bash -c \"ssh user#address; python file1.py; exec bash\"" -tab -e
"bash -c \"ssh user#address; python file2.py; exec bash\""
Wait for one of the python file to start executing before opening
another tab and repeating the process for another python file.
Also is there a better way to implement the same task ?
The above code snippet was from this thread.

You should consider using screen or tmux or a similar terminal multiplexer for this.
Example usage:
screen -d -m bash -c 'ls; bash'
to initiate a screen session in which ls was executed and then a shell started, and then
screen -X screen bash -c 'date; bash'
to create a new window in the existing screen session, run date therein and then start a shell in that window.
Mind that the programs are run without you seeing their output right away on your controlling terminal. You can then attach to the screen session using
screen -x
Which attach you to the running session and will show you one of the screen windows (the virtual terminals of your two running programs). Typing Ctrl-A n will switch through the windows, Ctrl-A d will detach you again, leaving the programs running, so you can attach later with screen -x.
You can attach from several locations (e. g. from two different Gnome-terminals) to the same running windows. Both will then show the same contents.
Another advantage of using screen is that you can log out and the programs keep running. If you later login again, you can still attach to the running sessions.
Only a direct attack like a reboot, a kill-signal or an interaction (like pressing Ctrl-C while being attached) will terminate your programs then.

Related

gnome-terminal -- $SHELL fails to execute the simplest commands

gnome-terminal -v -- $SHELL launches a new bash shell just as expected.
gnome-terminal -v -- $SHELL -c 'cd /' does nothing at all. A window briefly flashes, and that's it. Tried many other commands, like echo with the same result.
journalctl -f reveals Failed to start VTE child process 11350 launched by gnome-terminal-server process 7182. and that's it.
How do I debug this further?
this may not be the exact solution you need, but if you make a new profile for the terminal, and change the property "when command exits" to "hold terminal open"
then include the following argument:
gnome-terminal --window-with-profile=[new profile name here]
the new window will not briefly flash, and may allow more detailed debugging from whatever processes are called in the new window

Multiuser screen session from a shell script

I've looked up every tutorial i've found but none of them really answer my question.
I'm looking for a way to make a script which will :
Create a screen
Launch a "nodejs file.js" command in it
Distach
Make the screen accessible to every user from the group "devs"
For now here is the shell script I wrote :
#!/bin/bash
# Launcher script for js bot
screen -c ./_shared-conf/multi-screen.conf -dmS botScreen
screen -r botScreen
screen -d -m nodejs init_bot.js
and in the multi-screen.conf :
multiuser on
acladd rackover # adding every user manually as i don't know how to add group
acladd jj
Can you help me ? Thanks
Edit : I've been trying with TMUX, so far i've tried this :
Again, Alice and Bob ssh into the same server
Alice, as before, creates a new tmux session: tmux new -s alice. tmux will
implicitly create a new window group
Bob does not join that same session. Instead he starts a new session and
connects that session to the same window group as Alice’s session: tmux new -s bob -t alice
But this doesn't work neither.
The issue seems to be that your shell script will only launch the bot after you exit the screen. Let's go over what the commands do.
screen -c ./_shared-conf/multi-screen.conf -dmS botScreen
This creates a screen with the given config and doesn't attach.
screen -r botScreen
This attaches to the screen created before and thus waits until you exit or detach (Ctrl+A, D) from the screen.
screen -d -m nodejs init_bot.js
This creates another detached screen that runs the script.
The solution is to do it all in one command. To simply run the bot and then terminate the screen after the bot stops, add the nodejs command at the end:
screen -c ./_shared-conf/multi-screen.conf -dmS botScreen nodejs init_bot.js
If you want the screen to keep running after the bot stops, then you can use the solution from here:
screen -c ./_shared-conf/multi-screen.conf -dmS botScreen sh -c 'nodejs init_bot.js; exec bash'
This will run sh in the screen with the bot, then when the bot terminates runs bash to get an interactive shell within the screen.

How to enter keyboard shortcuts in bash script

Is it possible to enter keyboard shortcuts into a bash script? For example, I have tried typing in ^d to substitute for control + d (logout) without success.
ubuntu#vfleet:~$ ^d
-bash: :s^d: substitution failed
ubuntu#vfleet:~$ ^D
-bash: :s^D: substitution failed
I am using screen to run a django development server in the background. One of the commands to run a particular screen as a daemon is control + a + d. The goal is to be able to enter in control + a + d into a bash script. For example:
python manage.py runserver
^a + d
Is this possible?
Edit:
A valid method of avoiding the keyboard shortcut in screen is linked by Eric Renouf in the comments below. screen -d -m sh -c "python manage.py runserver" will start a development server as a daemon. This is a great solution for my particular problem, but it would still be nice to have a solution for the original question at hand.
xdotool package is the solution here.
xdotool key ctrl+d
Full reference
You probably should just start the command without attaching to the screen session in the first place, like
screen -d -m python manage.py runserver
but if you can't do that for some reason, you could detach from a screen session you're currently in by doing:
screen -S "$STY" -X detach
screen saves its current session info in STY, so we'll use that to make sure we're interacting with the correct session (in case there are many). Then we'll use -X to send a command to that session, in this case our command will be detach which will detach all the attached sessions, including the one used to execute that command
So while this doesn't actually send key strokes, it does highlight that there is often another command that you can send to accomplish your goals. Here detach takes the place of ctrl+a+d. Sending quit or running exit could often replace ctrl+d.
Another work-around would be to use expect which you could then use to send the strings containing control characters or hex values of them.

Pass command from scheduled script to program running in xterm window

I have a game server running in an xterm window.
Once daily I'd like to send a warning message to any players followed after a delay by the stop command to the program inside the xterm window from a script running on a schedule. This causes the cleanup and save functions to run automatically.
Once the program shuts down I can bring it back up easily but I don't know how to send the warning and stop commands first.
Typed directly into xterm the commands are:
broadcast Reboot in 2 minutes
(followed by a 2 minute wait and then simply):
stop
no / or other characters required.
Any help?
Do you also need to type something from the xterm itself (from time to time) or do you want your server to be fully driven from external commands?
Is your program line-oriented? You may first try something like:
mkfifo /tmp/f
tail -f /tmp/f | myprogram
and then try to send commands to your program (from another xterm) with
echo "mycommand" > /tmp/f
You may also consider using netcat for turning your program to a server:
Turn simple C program into server using netcat
http://lifehacker.com/202271/roll-your-own-servers-with-netcat
http://nc110.sourceforge.net/
Then you could write a shell script for sending the required commands to your "server".
If you know a little about C programming; I remember having once hacked the script program (which was very easy to do: code is short) in order to launch another program but to read commands from a FIFO file (then again a shell script would be easy to write for driving your program).
Something you might try is running your program inside a screen session.
You can then send commands to the session from cron that will be just
as if you typed them.
In your xterm, before launching the program do:
screen -S myscreen bash
(or you can even replace bash by your program). Then from your cron
screen -S myscreen -X stuff 'broadcast Reboot in 2 minutes\n'
sleep 120
screen -S myscreen -X stuff 'stop\n'
will enter that text. You can exit the session using screen -S myscreen -X quit
or by typing ctrl-a \.
screen is intended to be transparent. To easily see you are inside screen, you can
configure a permanent status bar at the bottom of your xterm:
echo 'hardstatus alwayslastline' >~/.screenrc
Now when you run screen you should see a reverse video bottom line. Depending
on your OS it may be empty.

how do i start commands in new terminals in BASH script

my bash script reads in a few variables and then runs airodump on my home network. I would like to keep the window with airodump running and open some new terminals to run other commands for network discovery while the airodump screen is open (so i can see the results).
right now what i have looks like this (edited for brevity):
#!/bin/bash
read -p "Enter the channel: $channel"
airomon-ng start wlan0 $channel,$channel
airodump-ng -c $channel,$channel mon0 &&
terminator -e netstat -ax &&
terminator -e nmap 192.168.1.1
the first command that uses the whole terminal (airodump) starts up fine and i can see the network, but then it just stays on that screen. If i ctrl+c then it goes back to prompt but i can see the error : Usage: terminator [options] error no such option
i want the netstat and nmap commands to appear and stay in their own terminal windows, how can i do this?
The terminal window is generated by a separate program from the command running inside. Try one of these variations:
xterm -e airomon-start wlan0 "$channel","$channel" &
gnome-terminal -x airomon-start wlan0 "$channel","$channel" &
konsole -e airomon-start wlan0 "$channel","$channel" &
Pick the command that invokes the terminal program you like. You'll have to do this for every command that you want run in its own window. Also, you need to use a single & at the end of each such command line -- not a double && -- those do totally different things. And the last line of your script should be just
wait
that makes it not exit out from under all the terminals, possibly causing them all to die.
Obligatory tangential shell-scripting nitpick: ALWAYS put shell variable uses inside double quotes, unless you know for a fact that you need word-splitting to happen on a particular use.
If the script is running in the foreground in the terminal, then it will pause while an interactive command is using the terminal. You could change the script to run airodump in a new terminal as well, or you could run the background commands before you start airodump (maybe after sleeping, if you're concerned they won't work right if run first?)

Resources