0

In our environment we have nearly 30 applications and 5 environments. Due to timeline issues, we have created 5[env]*3[three scripts per env]*30[num of applications]. It is 450 files.

We understand that we duplicated the code unnecessarily. If we have to change some mount point location for an environment, it has to be changed all over the applications.

So I have designed an approach with 3[files for all the applications] + 2[files to have app specific methods].

It is working fine. But the question here is that we need to pass 7 arguments to those three scripts.

So there was an argument saying that the script is bizarre and cumbersome. I would like to know what is the advised number of command line arguments to bash script.

I couldn't find any documentation related to this. But I referred this. It doesn't convincing me.

Any suggestions? Do I need to really rethink the design just for the sake of 7 parameters.

Note: I did. I have a solution with 3-5 parameters now. But I would like to know the recommended number of the arguments.

Gibbs
  • 21,904
  • 13
  • 74
  • 138
  • Common terminal commands can be _incredibly_ long sometimes. Having seven arguments isn't longer than some common commands I use with `grep` and `sed`.However, how long is too long will come down to personal preference. – ifconfig Jun 02 '18 at 04:11
  • The number of arguments doesn't matter. Give a coworker a man page and see if they can easily construct the command they want. If it's like `cp` where you just list individual files, it's fine to accept thousands. If it's like `ffmpeg` where most options have defaults and you just specify which parts of the encoding process you want to affect in any order, it's fine to have dozens. If it's like `clang` where options can be interdependent and the order of files matter for symbol resolution, then it can be a major hassle. – that other guy Jun 02 '18 at 04:22
  • Thanks @thatotherguy and ifconfig I understand from the samples you mentioned. – Gibbs Jun 02 '18 at 04:27
  • To add another example, you see very verbose invocations of the `find` command. – glenn jackman Jun 02 '18 at 13:56

2 Answers2

3

If the script expects seven specific, distinct parameters in a specific order, then — yes, I think that's too many. The difference between

foo.sh fred wilma pebbles dino barney betty bamm-bamm

and

foo.sh fred wilma pebbles barney betty bamm-bamm dino

is just too subtle; the order of parameters that makes most sense to the person writing the script will not be the same order that makes most sense to each person using it.

However, in many cases you can improve the situation by "naming" the parameters (and not worrying about the order):

foo.sh \
    --father-1=fred --mother-1=wilma --child-1=pebbles --pet-1=dino \
    --father-2=barney --mother-2=betty --child-2=bamm-bamm

is much easier to use confidently (especially if the script gives clear error-messages when a parameter is missing or appears twice).

ruakh
  • 175,680
  • 26
  • 273
  • 307
  • You can use [`getopt`](http://manpages.ubuntu.com/manpages/bionic/en/man1/getopt.1.html) to help the arg parsing. Look for an example file on your system for assistance: `locate getopt-parse.bash`. The bash builtin `getopts` is easier to work with but it only handles 1 letter option names. – glenn jackman Jun 02 '18 at 13:55
0

You can write one main script and use other scripts calling that one.

The main script could handle the parameters as designed in the wrappers. When you need to call it from env test, task run, application hello and other options from the commandline, use a wrapper like this file hello.sh

#!/bin/bash
# example calling master.sh function doit()
source master.sh
env=test
application=hello # or application_sh=${0##*/} and remove .sh later
check_input # call some application specific function checking the parameters
doit "${env}" "${application}" $*

Perhaps collect those wrappers in subfolders.

/prod
/prod/hello
/prod/run
/prod/monitor
/prod/.../application1
/prod/.../application2
/prod/.../application3
/prod/monitor/application30
/accp/...
/test/...
/dev1/...
/dev2/...

It would be even easier when you could deduct the environment somehow.

case ${hostname} in
   myprod) env=prod;;
   ..) env=something;;
   *) env=develop;;
esac
case ${mode} in
email|sms) 
  application=monitor;;
uk|us|nl|de) 
  application=hello;;
single_user|multithreaded) 
  application=run;;
junit_test) 
  application=run
  env=development;; # overrule env by hostname
esac
Walter A
  • 19,067
  • 2
  • 23
  • 43