I am pretty green when it comes to bash scripts and completely new to command line functionality in bash. I tried my hand at a script which is supposed to be useable both with command line arguments as well as manual setting of variable values, if the user prefers to edit the code directly.
The general idea is this:
- Define command line arguments for different functions using the while/case/getopt structure.
- Set the value of the variables of each option inside the respective case.
- Later, check if the command line argument was actually provided using an if case.
- if not, set the value to a default parameter there.
This way one can either use myscript.sh -i somestring
, or just set the variable associated with -i inside the if case manually. This way the script can also be run just by doing ./myscript.sh
.
I have figured out that the if cases I have in my code don't actually do anything, or at least not what I want them to. When I run the script without commandline arguments and then echo out the default values that should be set by the if cases, they are empty.
This means that the for loop later on in the script cannot work, since these variables haven't been set to anything. The line that the script gets stuck on is
slurm_file_string=$(cat $slurm_template_file | sed "s/INPUT_FILE/$gs_file/")
So idk how to implement what I'm trying to achieve and how to fix this "getting stuck issue". I need to change the if cases somehow so that the default values inside the if cases actually do something, but idk how.
Here's my code:
#!/bin/bash
# TODO:
# Need to figure out if I can launch all slurm jobs with "&" and let slurm handle the rest.
# Add scratch removal logic to slurm file template. Makes more sense to do it per run in the file that actually runs gaussian.
# Add commandline options for:
# input folder (-i)
# verbose mode (-v)
# extension name (-x)
# slurm template name (-t)
# Define function be_verbose() which wraps the logic for printing additional info if -v is set to true.
# INFO: Script for running a batch of gaussian jobs using the SLURM scheduler.
# General program flow:
# The script finds all gaussian input files in inps_folder (needs to be manually specified)
# The input files are identified by the file extension in "extension"
# The script iterates over all gaussian input files.
# For each file a slurm file is created based on the template: submit_gaussian_template.slurm
# Inside the template the string "INPUT_FILE" is replaced by the current input file.
# The new slurm file is copied to the input files folder
# The script changes directories to the common pwd of the slurm file and gaussian input file
# The slurm file is executed and then the next iteration starts.
# The cleanup is handeled by the shell code inside the slurm file (deleting temp files from /scratch)
# IMPORTANT:
# This script is designed for a certain folder structure.
# It is required that all your gaussian input files are located in one directory.
# That folder must be in the same dir as this script.
# There must be a template slurm file in the directory of this script
# There must be a string called INPUT_FILE inside the template slurm file
################################################################################################################################################
# this implements command line functionality. If you do not wish to use them, look for MANUAL_VARS_SPEC below to specify your variables that way.
while getopts "i:vx:t:" opt; do
case $opt in
i)
inps_folder="$OPTARG"
;;
v)
verbose=true
;;
x)
extension="$OPTARG"
echo "$extension"
;;
t)
slurm_template_file="$OPTARG"
;;
\?)
echo "Usage: $0 [-i input_folder] [-s value_s] [-k value_k]"
exit 1
;;
esac
done
# MANUAL_VARS_SPEC: Change the varibles to the appropriate values if you do not wish to use the comman line options.
# These are essentially the default settings of the script.
# folder for input files
if [ -n "$inps_folder" ]; then # "if the commandline option is an empty string (not set), set the variable to this value."
inps_folder="testinps"
fi
# verbose mode
if [ -n "$verbose" ]; then
verbose=0
fi
# file extension of your gaussian input files
if [ -n "$extension" ]; then
echo "AFASGSG"
extension="gin"
fi
# slurm template file name
if [ -n "$slurm_template_file" ]; then
slurm_template_file="submit_gaussian_template.slurm"
fi
# HELPER FUNCTIONS
function be_verbose(){
local print_string="$1" # set the first argument provided to the funtion to the local var "print_string".
if [ $verbose = true ]; then
echo "$print_string"
fi
}
echo "$inps_folder"
echo "$verbose"
echo "$extension"
echo "$slurm_template_file"
#### START OF MAIN LOOP.
files="${inps_folder}/*.${extension}" # iteratable for all gaussian input files.
for file in $files; do
gs_file=$(basename $file) # get the file without the preceeding path
gs_file_name="${gs_file%.*}" # get the file name without the extension
# Make a new slurm file for the current job based on the template slurm file in the pwd.
slurm_file_string=$(cat $slurm_template_file | sed "s/INPUT_FILE/$gs_file/") # get template and replace INPUT_FILE with gaussian input file. FAIL!!!!
slurm_file="${gs_file_name}.slurm"
echo "$slurm_file_string" > "$slurm_file" # write the string of the new slurm file to a new file
mv "$slurm_file" "${inps_folder}/${slurm_file}" # move the new slurm file to the inps_folder
cd "$inps_folder" # change directories so that slurm files can be executed
echo "Is running ${gs_file}" #PUT HERE WHATEVER THE COMMAND FOR RUNNIGN A SLURM FILE IS &
cd ..
done
Thanks in advance for any input.