0

I am trying to open a file through a script; as long as I pass the file as the first argument there are no problems; for instance:

$ cat textExample.txt 
Much I marvelled this ungainly fowl to hear discourse so plainly,
Though its answer little meaning- little relevancy bore;
For we cannot help agreeing that no living human being
Ever yet was blessed with seeing bird above his chamber door-
Bird or beast upon the sculptured bust above his chamber door,
With such name as "Nevermore."
$ ./tester.sh textExample.txt 
BEGIN PROGRAM
parse file
For we cannot help agreeing that no living human being

where tester.sh is written like this:

#!/bin/bash

# options
optstring=fh
Feature=0
Help=0
while getopts $optstring opt
do
  case $opt in
    f) Feature=1;;
    h) Help=1 ;;
    *) echo WRONG && exit 1 ;;
  esac
done

if [[ $Feature == 1 ]] ; then
    echo "This is a feature of the program"
elif [[ $Help == 1 ]] ; then
    echo "This is the help page"
fi

echo "BEGIN PROGRAM"
# assign file name
file=$1
echo "parse file"
grep 'cannot help' $file

exit 0

Only the -h flag works because there is an exit statement:

$ ./tester.sh -h
This is the help page
$ ./tester.sh -f
This is a feature of the program
BEGIN PROGRAM
parse file
grep: option requires an argument -- 'f'
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.

Therefore, I modified the script introducing a step to check if the argument is a flag:

#!/bin/bash

# options
optstring=fh
Feature=0
Help=0
while getopts $optstring opt
do
  case $opt in
    f) Feature=1;;
    h) Help=1 ;;
    n) Custom_name=$OPTARG ;;
    *) echo WRONG && exit 1 ;;
  esac
done

if [[ $Feature == 1 ]] ; then
    echo "This is a feature of the program"
elif [[ $Help == 1 ]] ; then
    echo "This is the help page"
    exit
fi

for i in $@ ; do
    if [[ "${i}" =~ "-" ]] ; then
        true
    else
        input=$i
    fi
done


echo "BEGIN PROGRAM"
# assign file name
echo "parse file"
grep 'cannot help' $input

exit 0

and the result is:

$ ./tester.sh -f
This is a feature of the program
BEGIN PROGRAM
parse file
$ ./tester.sh -f textExample.txt 
This is a feature of the program
BEGIN PROGRAM
parse file
For we cannot help agreeing that no living human being

The problem is: if I add another argument to save the line to a file of a name of choice, I have another problem. Modifying the file in:

#!/bin/bash

# options
optstring=fhn:
Feature=0
Help=0
output=
while getopts $optstring opt
do
  case $opt in
    f) Feature=1;;
    h) Help=1 ;;
    n) output=$OPTARG ;;
    *) echo WRONG && exit 1 ;;
  esac
done

if [[ $Feature == 1 ]] ; then
    echo "This is a feature of the program"
elif [[ $Help == 1 ]] ; then
    echo "This is the help page"
    exit
fi

for i in $@ ; do
    if [[ "${i}" =~ "-" ]] ; then
        true
    else
        input=$i
    fi
done


echo "BEGIN PROGRAM"
# assign file name
echo "parse file"
if [[ -z $output ]] ; then
    grep 'cannot help' $input
else
    grep 'cannot help' $input > $output
fi

exit 0

the output is:

$ ./tester.sh -f textExample.txt 
This is a feature of the program
BEGIN PROGRAM
parse file
For we cannot help agreeing that no living human being
$ ./tester.sh -f -n my_file textExample.txt 
This is a feature of the program
BEGIN PROGRAM
parse file
$ ./tester.sh -n my_file textExample.txt 
BEGIN PROGRAM
parse file

That is: there is no input file anymore, bash is looking at the argument my_file as the input file.

I have been thinking to bracket the output file in single or double quotes and check for their presence, but I can't escape the quote, thus I get an error. Modifying the section:

for i in $@ ; do
    if [[ "${i}" =~ "-" ]] ; then
        true
    elif [[ "${i}" =~ \' ]] ; then
        true
    else
        input=$i
    fi
done

I get:

$ ./tester.sh -n 'my_file' textExample.txt 
BEGIN PROGRAM
parse file

That is, bash does not recognize the quotes in the argument. I tried different options such as "\'", '\'' etc as well as $i, "$i".

Is there a way to check the presence of quotes in an argument? Or a better way to handle arguments?

closed as too broad by Ipor Sircer, msp9011, A.B, Thomas, Archemar Sep 1 '18 at 9:11

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

1

After processing the options with getopts, the variable OPTIND is set to the index of the first non-option argument, so do this:

while getopts $optstring opt; do
    #... 
done
# now, remove the options from the positional parameters
shift $((OPTIND-1))

Now, $1 contains the filename.

  • Perfect! it works even without the quote markings: ./tester.sh -n 'my_file' textExample.txt BEGIN PROGRAM parse file $ cat my_file For we cannot help agreeing that no living human being $ ./tester.sh -n my_file textExample.txt BEGIN PROGRAM parse file $ cat my_file For we cannot help agreeing that no living human being. Thank you! – Gigiux Sep 3 '18 at 6:30

Not the answer you're looking for? Browse other questions tagged or ask your own question.