1

I have a Bash script that needs to call a command that will require quotes for one of it's arguments. When I run the command

myTimeCommand --time="2018 04 23 1100" -o /tmp/myOutput ~/myInput

from the command line, it works fine. In my script, I want to pass "2018 04 23 1100" as a parameter and send it directly to the command.

myScript --time="2018 04 23 1100"

But, when I try this, I get an error message that

""2018" is not a valid time.

I'm using getopt to parse the parameters. Here's my script

OPTIONS=t:
LONGOPTIONS=time:

PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTIONS --name "$0" -- "$@")
echo ${PARSED}

# read getopt’s output this way to handle the quoting right:
eval set -- "$PARSED"

# now enjoy the options in order and nicely split until we see --
while true; do
    echo "option: ${1}"
    case "$1" in
        -t|--time)
            timeBase="$2"
            timeBase="--time=\"${timeBase}\""
            shift 2
            ;;
        --)
            shift
            break
            ;;
        *)
            echo "Programming error"
            exit 3
            ;;
    esac
done

echo ${timeBase}

myTimeCommand ${timeBase} -o /tmp/myOutput ~/myInput

EDIT: Removed the runCommand() function. While this produced some good comments, detracted from the issue at hand - copying quoted parameters to run with a command.

Second example: Text file (myTest.txt) with

I have a Bash script that needs to call a command that will require quotes for one of it's arguments.  When I run the command

myTimeCommand --time="2018 04 23 1100" -o /tmp/myOutput ~/myInput

from the command line, it works fine.  In my script, I want to pass "2018 04 23 1100" as a parameter and send it directly to the command.

When I run grep "command line" myTest.txt I get a hit for the last line (as expected). When I modify the script to

OPTIONS=s:
LONGOPTIONS=str:

PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTIONS --name "$0" -- "$@")

echo ${PARSED}

# read getopt’s output this way to handle the quoting right:
eval set -- "$PARSED"

# now enjoy the options in order and nicely split until we see --
while true; do
    echo "option: ${1}"
    case "$1" in
        -s|--str)
            sStr="\"$2\""
            shift 2
            ;;
        --)
            shift
            break
            ;;
        *)
            echo "Programming error"
            exit 3
            ;;
    esac
done

echo "grep ${sStr} myTest.txt"

grep ${sStr} myTest.txt

The echo shows the command as expected, but the actual grep fails

-bash-4.2~>./extText --str="command line"
grep "command line" myTest.txt
grep: line": No such file or directory

How do I call grep with the parameter I passed in ("command line" in this case)?

codeforester
  • 39,467
  • 16
  • 112
  • 140
doobop
  • 4,465
  • 2
  • 28
  • 39
  • Try with `cmd=$(printf 'myTimeCommand "%s" -o /tmp/myOutput ~/myInput' "${timeBase}"`. Use the timeBase plain value, without adding any quote. – LMC Apr 24 '18 at 14:28
  • 5
    I'm trying to put a command in a variable, but the complex cases always fail! [BashFAQ/050](http://mywiki.wooledge.org/BashFAQ/050) – glenn jackman Apr 24 '18 at 14:43
  • @LuisMuñoz, that has the same fault the OP's original code does -- it's still generating a string with literal quotes when syntactic ones are needed; however, expansion of a string *doesn't parse quotes as syntax*, so quotes from a string expansion will never be syntactic (unless using `eval`, calling a new shell with a string passed as code, or another equivalent to force reparse from the beginning -- all of which cause larger problems). – Charles Duffy Apr 24 '18 at 15:33
  • @charles-duffy, appreciate the clarification. Will try this stuff later. – LMC Apr 24 '18 at 16:16

1 Answers1

5

Don't use variables for running commands! They are used to hold data and not functions. Use an array

cmdArray=()
cmdArray=( "myTimeCommand" "${timeBase}" "-o" "/tmp/myOutput" "~/myInput" )

and pass the quoted array to prevent from word-splitting

runCommand "${cmdArray[@]}"

See BashFAQ/050 - I'm trying to put a command in a variable, but the complex cases always fail!

Inian
  • 80,270
  • 14
  • 142
  • 161