1

I am having problem allowing my script to take more than three arguments. My script will take commands like this, for example:

./myscript.sh -i -v -r filename

so far if it only takes two arguments plus filename:

./myscript.sh -i -v filename

If I run the full commands, [-i] [-v] [-r] it gives this errors...

"mv: invalid option -- 'r' Try 'mv --help' for more information."

here is my code so far....

#!/bin/bash

dirfile='.trash'

verbose=

function helpfunction()
{
    echo "=============== HELP COMMAND ============="
    echo ""
    echo "-h | --help"
    echo "-i | --interactive"
    echo "-v | --verbose"
    echo "-r | --recursive"
    echo ""
}

if [ $# -eq 0 ]; then
    echo "no commands"
    exit 1
fi


option="${1}" 
case ${option} in 
     -h | --help)
            helpfunction
            exit
      ;;

    #interactive -i or --interactive
     -i) FILE="${*}" 
      echo "File name is $FILE"
            echo -n "Do you want to remove this file (y/n)? "
            read answer
            if echo "$answer" | grep -iq "^y" ;then
                mv $FILE $dirfile
            fi
      ;;

    #verbose -v or --verbose
     -v) FILE="${*}"
            if [ -f "$FILE" ]; then
                -v $FILE
            fi
      ;;

    #recursive -r or --recursive
     -r) FILE="${*}"
            if [ -d "${*}" ]; then
                rm -r "$FILE"
            fi
      ;;

    #unremove -u or --unremove
        -u) FILE="${*}"
                for file in $dirfile*; 
                do
                    if [[ -f $file ]]; then
                        echo "file found"
                    else
                        echo "File not found"
                    fi
                done
            ;;

    #list -l or --list
        -l) FILE="${*}"
                for entry in "$dirfile"/*
                do
                    echo "$entry"
                done
            ;;

        *)  
          echo "`basename ${0}`:usage: [-f file] | [-d directory]" 
          exit 1 # Command to come out of the program with status 1
           ;; 
esac 
codeforester
  • 39,467
  • 16
  • 112
  • 140
jojo so
  • 11
  • 1
  • 4
  • Make the required entries first in the list – soft87 Sep 30 '17 at 16:19
  • how though? I am new to shell script. – jojo so Sep 30 '17 at 16:20
  • the first argument is filename ($1) – soft87 Sep 30 '17 at 16:29
  • Have you explored `getopt`? That is your best bet when you have many options and some options take arguments as well. Check this post: https://stackoverflow.com/questions/16483119/example-of-how-to-use-getopts-in-bash – codeforester Sep 30 '17 at 18:10
  • 1
    There's much more than just one bug here, which makes your question's scope rather... extended. Please try to isolate a question to be around just *one* problem, and build a [mcve] that reproduces only that single issue when asking a question. (It would also be helpful to fix the issues detected by http://shellcheck.net/ before coming here). – Charles Duffy Sep 30 '17 at 19:59
  • In addition to the flagged duplicates, this also falls rather squarely into [BashFAQ #35](http://mywiki.wooledge.org/BashFAQ/035). – Charles Duffy Sep 30 '17 at 20:02

2 Answers2

0

When you say

FILE="${*}"

You're taking all the remaining arguments as one string, and assigning that to FILE. You can see this by adding 'set -x' to the top of your script:

opus$ ./myscript.sh -i -v -r filename
+ '[' 4 -eq 0 ']'
+ option=-i
+ case ${option} in
+ FILE='-i -v -r filename'
+ echo 'File name is -i -v -r filename'
File name is -i -v -r filename
+ echo -n 'Do you want to remove this file (y/n)? '
Do you want to remove this file (y/n)? + read answer
y
+ grep -iq '^y'
+ echo y
+ mv -i -v -r filename
mv: invalid option -- 'r'
Try 'mv --help' for more information.

Saying $1 gives the first argument. After you discover that, you can use shift to load the next argument as $1, and cycle through them like that.

Alternatively, you could just use the builtin getops argument parser.

Joe

0

You are getting error at this line mv $FILE $dirfile

Here is the execution of your script in debug mode.

bash -x ./myscript.sh -i -v -r test.txt
+ dirfile=.trash
+ verbose=
+ '[' 4 -eq 0 ']'
+ option=-i
+ case ${option} in
+ FILE='-i -v -r test.txt'
+ echo 'File name is -i -v -r test.txt'
File name is -i -v -r test.txt
+ echo -n 'Do you want to remove this file (y/n)? '
Do you want to remove this file (y/n)? + read answer
y
+ echo y
+ grep -iq '^y'
+ mv -i -v -r test.txt .trash
mv: invalid option -- 'r'
Try 'mv --help' for more information.

-r is not a valid argument for mv.

Update your script like FILE=$4 if you want -i -v -r as optional, you can extract the last argument following this Getting the last argument passed to a shell script

You can also use ${!#} for getting the last parameter.

Shahzeb Khan
  • 3,582
  • 8
  • 45
  • 79