Back to list
bash, screen and automation
Published
In linux cli 
Long

bash, screen and automation

Starting a new job in IT brings always new fun moments to speed up things by automating CLI tasks.

This post describes my new setup.

My environment consists of maven mixed with NPM related tooling so there are some magical commands to run from time to time (and I fail to remember them). There is also a need to run with Java 8 on this project.

Where it starts

In my .bashrc, I added a function to "start working":

function __work {
source /path/to/work.local.rc
}

Where everything initializes

The work.local.rc contains an init segment where I define environment variables and check for the presence of some tools. I have more that one machine and I want to be able to ramp up fast when changing machines:

# INIT

# basic tools
which screen > /dev/null || yay screen

# java 8
JAVA8_HOME=/usr/lib/jvm/java-8-openjdk
if [[ ! -e $JAVA8_HOME ]]; then
echo "Installing java 8, prepare to be root!"
yay java8
fi
export PATH=${JAVA8_HOME}/bin:${PATH}

# atlassian
ATLASSIAN_SDK=/opt/atlassian/plugin-sdk/
if [[ ! -e $ATLASSIAN_SDK ]]; then
echo "Installing atlassian-plugin-sdk, prepare to be root!"
yay atlassian-plugin-sdk
fi
export PATH=${ATLASSIAN_SDK}/bin:${PATH}
export ATLAS_MVN=/opt/maven/bin/mvn

# ...

Some of the scripts relies on screen so we check if it is available. If not, it is installed with yay (ArchLinux).

Next we setup Java 8 for this terminal. Again, it is installed if missing.

Same for the Atlassian plugin SDK, everything is available in Archlinux User repository!

The functions

Still in work.local.rc, I define functions that will simplify my life, e.g making sure the commands run in the correct directory.

Function with a single task

# INIT

# ...

function installAll {
__info "Running maven install task"
__warn "Grab a coffee, this is going to take a while"
sleep 5
pushd $T_HOME
atlas-mvn install -DskipTests
popd
}

function rebuildAll {
__info "Running maven clean install tasks"
__warn "Grab a coffee, this is going to take a while"
sleep 5
pushd $T_HOME
atlas-mvn clean install -DskipTests
popd
}

Functions with multiple tasks -- screen

I struggle a little to find a way to start more than one application in a screen.

I ended up with the following:

function startAll {
__info "Start all servers"

screen -ls server > /dev/null
if [ $? = 0 ]; then
echo "A server app screen container is running kill it to continue."
return 1
fi

# create a new screen session and name the first window
screen -mdS server -t api
# create other windows in the same session
screen -S server -X screen -fn -t host bash
screen -S server -X screen -fn -t ssh bash
# paste stuff to run in respective windows
screen -S server -p api -X stuff $"cd $T_HOME && atlas-mvn spring-boot:run -f path/to/api\n"
screen -S server -p host -X stuff $"cd $T_HOME && atlas-mvn spring-boot:run -f path/to/host\n"
screen -S server -p ssh -X stuff $'ssh my.server.home -L45455:localhost:8081\n'
}

First we check if the named screen session:

screen -ls server
if [ $? = 0 ]; then
echo "A server app screen container is running kill it to continue."
return 1
fi

I prefer not to manage the shutdown through these scripts.

I create a new named screen session (server) and name the first window (api):

screen -mdS server -t api

I add two windows (hostand ssh) to the server screen session using the -X screen option.

screen -S server -X screen -fn -t host bash
screen -S server -X screen -fn -t ssh bash

I start the scripts using the -X stuff $'command\n':

screen -S server -p api -X stuff $"cd $T_HOME && atlas-mvn spring-boot:run -f path/to/api\n"
screen -S server -p host -X stuff $"cd $T_HOME && atlas-mvn spring-boot:run -f /path/to/host\n"
screen -S server -p ssh -X stuff $'ssh my.server.home -L45455:localhost:8081\n'

The last line handle a reverse connection to my external proxy to be "reachable" from outside.

Finally

As I don't use all the functions all the time I add another one to list to remind me of all the functions in the file:

me=${BASH_SOURCE}

function all {
local BOLD=$(tput bold)
local NORM=$(tput sgr0)
echo "${BOLD}Available here"
for i in `grep ^function ${me} | grep -v ${FUNCNAME[0]} | cut -d' ' -f 2`; do
local description=$(grep -A 1 ${i} ${me} | grep __info | sed 's/^\W*__info //')
echo "- ${BOLD}${i}${NORM} -- ${description}"
done
}

There are 3 "bashisms":

The function all retrieves all the functions in the file ($me) and retrieves the line below each function name to display both like this:

$ all
**Available here**
- **installAll** -- "Running maven install task"
- **rebuildAll** -- "Running maven clean install tasks"
- **startAll** -- "Start all servers"

**Available here** is bold in the terminal.