Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bash getopts can't assign value to variable

Tags:

bash

I'm setting variable dag='false' at beginning, if -d argument is provided then getopts set dag='true', but it still is false. Here is the my code:

#! /usr/bin/bash

dag='false'
replacement=''

print_usage() {
  echo "Usage: `basename $0` [-h] [-d] [-r]"
  echo "This script find all texts that match the given text pattern in the given repository,"
  echo "then delete these texts or replace them with new text if -r is given, reformat each files."
  echo "Optionally, it can generate DAG which can be used as test plan."
  echo
  echo "Syntax: remove_optin_filters.sh <path to repository> <regex-style match pattern> -r(optional) <replacement> -d(optional, to generate DAG)"
  echo
  echo "positional arguments:"
  echo "path_to_repository          path to the desired directory"
  echo "match_pattern               regex-style pattern to match text"
  echo
  echo "options:"
  echo "-h                          Print this Help"
  echo "-d                          Generate DAG to all files changed and save them to pastry"
  echo "-r                          replace text with provided text"
  exit 0
}

while getopts 'dhr:' flag; do
  case "${flag}" in
    d) dag='true' ;;
    h) print_usage ;;
    r) replacement="${OPTARG}" ;;
    \?) echo "Incorrect usage";;
  esac
done

echo $dag

# first argument is the repository path
repo=./$1

# second argument is the regex pattern to match text
pattern=$2

# find all files+patterns in given repository that match the given pattern,
# and save to sg file. (sg is temp file and will be removed at the end)
find $repo -type f -name "*.py" -exec grep -iH "$pattern" {} \; > sg

# retrieve all the file pathes. Dedup, sort and remove the trailing colon
# save them to sg_unique file. (sg_unique is temp file and will be removed at the end)
cat sg | awk '{ print $1; }' | uniq | sort > sg_unique
sed -i "s/:$//" sg_unique

# remove or replace the texts from all files
if [ "$replacement" == "" ]
then
  for l in $(cat sg_unique); do sed -i "s/$pattern//ig" $l; done
else
  for l in $(cat sg_unique); do sed -i "s/$pattern/$replacement/ig" $l; done
fi

# format all files
for l in $(cat sg_unique); do arc dsfmt $l; done

# option(flag = -d): generate DAG for all files and save them to pastry
if [ "$dag" == "true" ];
then
  echo "Generate DAG..."
   for l in $(cat sg_unique); do echo "$l"; ./status --tree -q $l; echo ""; done |& pastry
else
  echo "No DAG verified"
fi

# clean out temp files
rm sg
rm sg_unique

Here is the command:

./remove_optin_filters.sh <repository> "AND COALESCE(privacy_optin_flag, 'ON') = 'ON'\|AND latest_privacy_optin_flag = 'ON'\|AND privacy_optin_flag = 'ON'" -d

Result:

false
No DAG verified
like image 993
JamesWang Avatar asked Aug 11 '26 00:08

JamesWang


1 Answers

while getopts 'dhr:' f
do
    echo "$f"
done
./testgetopts.sh -d -h x -r -d

d
h

In other words, getopts returns false (non-0 exit code) as soon as it encounters something else.

Your -d flag is after many things that are not what getopts is looking for

Try with

./remove_optin_filters.sh -d <repository> "AND COALESCE(privacy_optin_flag, 'ON') = 'ON'\|AND latest_privacy_optin_flag = 'ON'\|AND privacy_optin_flag = 'ON'" 

Or, in the scrpit, read the directory first, then shift, then copy the filter, then shift, and then getopts

mydir="$1"
myfilter="$2"
shift 2

while getopts 'dhr:' f
do
    echo "$f"
done

This time

./trygetopts foo bar -d

shows the expected d

like image 164
chrslg Avatar answered Aug 12 '26 14:08

chrslg