0

I am very much new to shell script and i want to create and run shell script.

I want to run my java program in two different environment which is simu and prod.

If i am running the program in the simu environment then execute SIMU_RUN else PROD_RUN.

For example i have two directory where file is placed in /data/etl-simu/in/ and /data/etl-prod/in/ and as you can see while reading the file from the directory name i can recognise whether the environment is simu or prod from SIMU_PATH or PROD_PATH variable.

I am not sure if it easy to write such shell script and execute it.

If i just create normal shell script and put the complete SIMU_RUN or PROD_RUN path in that shell script and execute it then in the respective environment then it will run fine. But as i have two environment then i want to make this shell script flexible instead of creating two separate shell script for simu and prod

#!/bin/sh

SIMU_RUN="cd /opt/env/import/import/current; java -Dlog4j.configurationFile=/opt/import/config/logging/log4j2_Importer.xml -Djava.security.egd=file:///dev/urandom -classpath /opt/runner/lib/*:/opt/import/lib/* runner.Application --config /opt/import/config/import.simu.properties --workflow import --inputDir /data/etl-simu/in"
PROD_RUN="cd /opt/import/import/current; java -Dlog4j.configurationFile=/opt/import/config/logging/log4j2_Importer.xml -Djava.security.egd=file:///dev/urandom -classpath /opt/runner/lib/*:/opt/import/lib/* runner.Application --config /opt/import/config/import.prod.properties --workflow import --inputDir /data/etl-prod/in"

SIMU_PATH="/data/etl-simu/in"
PROD_PATH="/data/etl-prod/in"

MODE=$1

if [ "${MODE}" = SIMU_PATH ]; then

#execute SIMU_RUN

else
  #execute PROD_RUN


fi

exit ${EXIT}
Andrew
  • 3,632
  • 24
  • 64
  • 113
  • See [BashFAQ #50](http://mywiki.wooledge.org/BashFAQ/050), which is precisely on-point for this problem (and gives the same advice as glenn jackman's correct answer below). – Charles Duffy Feb 04 '20 at 17:16
  • ...in reading the linked duplicate, I strongly recommend ignoring the accepted answer (which gives advice that is actively harmful to both security and correctness, as described in its comments and in [BashFAQ #48](http://mywiki.wooledge.org/BashFAQ/048)). – Charles Duffy Feb 04 '20 at 17:19
  • hi charles still i am getting error with the answer from glenn as Invalid Mode..i dont know for what reason the question is closed as it doesnt look duplicate – Andrew Feb 05 '20 at 09:43
  • The reason is that it's the same underlying mistake with the same underlying set of possible resolutions, even if the manifestations differ. Have you read the BashFAQ #50 link yet? – Charles Duffy Feb 05 '20 at 13:36
  • yes i have read the BashFAQ #50 but didn't saw the answer which is relative to my question may be as i mentioned i am quiet beginner – Andrew Feb 05 '20 at 13:42
  • As something more explicit and less clever (though I really do suggest doing the work to figure out what's wrong with the clever approach and doing that instead): https://gist.github.com/charles-dyfis-net/fe51b0f341b3c05e1161e0d7038dd54f – Charles Duffy Feb 05 '20 at 13:47
  • 1
    ...to be clear, the reason your question is being about putting commands in variables, instead of being about parameterization, is that *that's the mistake you're making*. You aren't making any mistakes about paramaterization in the code you show us, you're only showing us code that tries to store code as data; thus, you get marked as a duplicate of a question where the mistake is storing code as data (instead of, by using a function, storing code as code). – Charles Duffy Feb 05 '20 at 13:52

1 Answers1

2

Don't store code in a variable, use a function:

#!/bin/sh

run() {
    cd /opt/import/import/current &&
    java -Dlog4j.configurationFile=/opt/import/config/logging/log4j2_Importer.xml \
         -Djava.security.egd=file:///dev/urandom \
         -classpath /opt/runner/lib/*:/opt/import/lib/* \
         runner.Application \
         --config "/opt/import/config/import.${mode}.properties" \
         --workflow import \
         --inputDir "/data/etl-${mode}/in"
}

mode=$1

case "$mode" in
    prod|simu) 
        run 
        ;;
    *)  echo "error: invalid mode" >&2
        exit 1
        ;;
esac

Notes:

  • Get out of the habit of using ALLCAPS variable names, leave those as reserved by the shell. One day you'll write PATH=something and then wonder why your script is broken.
  • I've broken up the very long lines with line continuations: that will make maintainability much easier.

If you make this a script, then it's even nicer IMO:

run() {
    local -a java_options=(
        -Dlog4j.configurationFile=/opt/import/config/logging/log4j2_Importer.xml
        -Djava.security.egd=file:///dev/urandom
        -classpath "/opt/runner/lib/*:/opt/import/lib/*"
    )
    local app="runner.Application"
    local -a app_options=(
         --config "/opt/import/config/import.${mode}.properties"
         --workflow import
         --inputDir "/data/etl-${mode}/in"
    )

    cd /opt/import/import/current &&
    java "${java_options[@]}" $app "${app_options[@]}"
}
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • Hi glenn i am trying your first script but its missing small part ..we also need to handle dbimport.simu.properties and place simu or prod accordingly here...this is very important as this will determine database properties...is it possible to place parametarized variable there like you did to replace path? – Andrew Feb 05 '20 at 07:20
  • @Andrew, the code *does* recognize `simu_path` and `prod_path` given as arguments, and passes whichever one it's given as `$1`, so it's substituted into the app_options. – Charles Duffy Feb 05 '20 at 13:49
  • @Andrew, ...the difference between `/data/etl-simu/in` and `/data/etl-prod/in` in your two hardcoded commands is the only difference that doesn't look, on its face, like a typo. If that's untrue, please be explicit. – Charles Duffy Feb 05 '20 at 13:50
  • @Andrew I've updated the answer: pass "prod" or "simu" to the script, and the "run" function uses the variable in 2 places. This makes the code a little cleaner. – glenn jackman Feb 05 '20 at 13:51
  • yes it works thanks :) and i just have to pass like "prod" or "simu" in argument while running the script instead of path – Andrew Feb 05 '20 at 14:35