Home > Enterprise >  How to automate adding external scripts into the main script code with bash
How to automate adding external scripts into the main script code with bash

Time:11-12

Note: please give feedback on the title, I honest didn't know how to title this question.

Im trying to design a code that everytime the user drop a file in the tools folder, it automatic gets add into the main code at menu.sh script, so it's simpler for the user.

The menu.sh is working fine, but everytime the user adds a new script he needs to do add two lines of code in the main script(menu.sh)

for example, lets say the user want to add a script called run-scrape.sh

"run-scrape" need to be added:
-options variable
-added in the source command inside the case statment

I am trying to automate this two tasks so it's simpler for the user.

I am open to a different approach to do this or link to something similar, I couldn't find anything like.

Background:

folder structure:

~ 
scripts  
menu.sh, tools 
> cd tools
pushing-code.sh,  purge-data.sh, run-scrape.sh

menu.sh :

title="title"

prompt="Pick an option(number): "

options=(         
        "pushing code" \
        "purge-data" \
        "run-scrape" \
         )

echo "$title"
PS3="$prompt"
select opt in "${options[@]}" "Quit"; do 
    case "$REPLY" in
    0) source $(pwd)/scripts/tools/pushing-code.sh; my_func;;
    0) source $(pwd)/scripts/tools/purge-data.sh; my_func;;
    0) source $(pwd)/scripts/tools/run-scrape.sh; my_func;;

    $((${#options[@]} 1))) echo "Goodbye!"; break;;
    *) echo "Invalid option. Try another one.";continue;;
    esac
Working the Solution:

basically some how need to create this two components in the menu.sh code:

  1. The variable: options

    myFileNames=$(ls ~/$(pwd)/scripts/tools)
    for file in $myFileNames;
    
  2. The case statement
    the following line of code will be the same for every file except for the file name, in this example: pushing-code.sh

    so adding this to the menu.sh code:

    #sample:  0) source $(pwd)/scripts/tools/pushing-code.sh; my_func;
    
    path=$(pwd)
    args=()
    for i in myFileNames; do
        args=("0) source $path/scripts/tools/$i ; my_func;")
    done
    
    select opt in "${options[@]}" "Quit"; do 
        case "$REPLY" in args
    
        $((${#options[@]} 1))) echo "Goodbye!"; break;;
        *) echo "Invalid option. Try another one.";continue;;
        esac
    

I don't think it's well put together, does anyone have done something similar in the past that would share the code :)

CodePudding user response:

1: The variable: options

myFileNames=$(ls ~/$(pwd)/scripts/tools)
for file in $myFileNames;
  • Use pathname expansion (globbing), not ls.
  • And use it to populate an array, not a flat string. Also
  • ~/$(pwd)/scripts/tools does not make sense.

Overall, something along these lines

# Create an array of all the *.sh files in the tools directory
options=(/path/to/tools/*.sh)

You can check the result by, for example,

echo "${options[@]}"

2: The case statement the following line of code will be the same for every file except for the file name, in this example: pushing-code.sh

Having the options in an array, you can access each one via its index. That pairs nicely with using select, something along these lines:

# Select from among elements of the options array
select choice in "${options[@]}"; do
  if [[ -n "$choice" ]]; then
    # read and evaluate the commands from the selected file
    # select options are numbered from 1, but array indices from 0
    source "${options[$((choice - 1))]}"
    break
  else
    echo "$REPLY" is not a valid selection
    # ...
  fi
done

The select command will automatically loop until a break command is executed or EOF is reached on the standard input.

  • Related