I am writing a bash script that receives <task>
ID strings as a parameter and then executes the specified tasks. At the end of the execution, it must show the total execution time. The code must be flexible, and easy to add new conditions.
Usage: build.sh <task><task><task>...
The task id is a little bit tricky:
- if it is only a character [a-z] then it represents all subtasks of the given task
- if it is a character a number, it represents only the specific subtask
Let me give you some examples:
build.sh a1a2
: execute tasks ofa1
anda2
, but nota3
build.sh a
: execute all tasks starts with chara
(all subtasks ofa
)build.sh a1b
: run only taska1
and all subtasks ofb
build.sh a1b3
: run only taska1
andb3
build.sh ab
: run all subtasks ofa
andb
build.sh *
: run all tasks defined is the build script (all subtasks), likea
b
c
The execution order of the tasks is pre-defined, so actually b1a1
will execute a1b1
.
This is my bash script:
#!/bin/bash -ue
# show help
function show_help() {
if [ "$1" -eq 0 ]; then
printf "..."
exit 0
fi
}
# does the build
function build {
local title dir
title="$1"
dir="$2"
printf "\n%b> building '%s'...%b\n" "$COLOR_YELLOW" "$title" "$COLOR_DEFAULT"
cd "$WORKSPACE/../$dir"
./build.sh
cd "$WORKSPACE"
}
# group A build
function build_group_a {
if [[ "$1" == *a1* ]]; then build "task A.1" "base/xxx"; fi
if [[ "$1" == *a2* ]]; then build "task A.2" "base/yyy"; fi
if [[ "$1" =~ $(getRegexp a) ]]; then
build "task A.1" "base/xxx"
build "task A.2" "base/yyy"
fi
}
# group B build
function build_group_b {
# same with 'build_group_a' only conditions are different
}
# REGEXP THAT DOES NOT WORK PROPERLY
function getRegexp() {
printf ".*%s[a-z].*" "$1"
}
show_help "$#"
START_TIME=$(date %s)
# 'all' works but '*' not
if [[ "$1" == all ]]; then
build_group_a a
build_group_b b
else
build_group_a "$1"
build_group_b "$2"
fi
ELAPSED=$(($(date %s) - START_TIME))
printf "build time: %s\n" "$(date -d@$ELAPSED -u %H\ hour\ %M\ day\ %S\ sec)"
Everything works fine, tasks are executed properly in order but if I use build.sh a
then nothing is executed. If I use build.sh ab
, only tasks a
are executed. I do not know why. It seems that the last task-ID is not processed by my regexp.
Another issue is that if I say build.sh aa1
then all tasks for a
are executed but task a1
twice. Task a1
must only be executed once when a
is called.
That could be great if you can guide me on how to fix the problem in my regular expression.
CodePudding user response:
On the regex part, you can try this :
#!/usr/bin/env bash
input="$1"
pattern='(\*|[[:alpha:]][[:digit:]]?)'
while [[ $input =~ $pattern ]]; do
echo "Argument passed : ${BASH_REMATCH[1]}"
input="${input:${#BASH_REMATCH[0]}}" # next iteration
done
test with :
bash build.sh a1b
bash build.sh "*"
CodePudding user response:
Thanks a lot for your comments. Based on your help I was able to fix the issue. In the final version I use a little bit different approach for the regexp than before. And in the meanwhile I simplified everything.
This is the code with the regexp:
#!/bin/bash -ue
function build {
local arg id title dir group regexp
arg=$(printf "%sz" "$1")
id="$2"; title="$3"; dir="$4"; group=${id:0:1}
regexp=$(printf "(0|%s|%s[a-z])" "$id" "$group")
if [[ "$arg" =~ $regexp ]]; then
printf "%b> building '%s'...%b\n" "$COLOR_YELLOW" "$title" "$COLOR_DEFAULT"
cd "$WORKSPACE/.../$dir"
./build.sh
cd "$WORKSPACE"
fi
}
function show_help() {
if [ "$1" -eq 0 ]; then
printf "..."
exit 0
fi
}
...
show_help "$#"
START_TIME=$(date %s)
build "$1" "a1" "task A.1" "aa/xxx"
build "$1" "a2" "task A.2" "aa/yyy"
build "$1" "b1" "task B.1" "bb/vvv"
build "$1" "b2" "task B.2" "cc/www"
ELAPSED=$(($(date %s) - START_TIME))
printf "build time: %s\n\n" "$(date -d@$ELAPSED -u %H\ hour\ %M\ day\ %S\ sec)"
This works like a charm and I think that it is enough simple.
I use 0
to run all of the tasks because unfortunately, the asterisk(*
) was not working for me in my regexp.
Another trick that I had to do is to add an extra character (in my case it is an z
) at the end of the user input. That was necessary, otherwise, the last command won't be executed.