0

I am trying to accept a quoted parameters in bash similar to:

$ git commit -m "message as a sentence"

or

$ something "foo bar"

And from that, I would like to extract message as a sentence and foo bar.

What I have done so far is:

if [[ "$2" =~ "-m" ]]; then
  if [ -z $3 ]; then
    echo  "Must have a message"
  else
    # @TODO
  fi
fi

Any ideas?

Abraham
  • 8,525
  • 5
  • 47
  • 53
  • 1
    Something including `getopts 'm:'` seems like a good start. – Benjamin W. Jun 30 '18 at 06:07
  • The quotes aren't special, they just make that the argument to the `-m` option is not split. – Benjamin W. Jun 30 '18 at 06:08
  • `-m` is just the argument before where I need to parse the complete sentence as an argument – Abraham Jun 30 '18 at 06:10
  • 1
    The problem is the quotes will be handled and removed **by the shell** prior to you receiving the positional parameters in your script. `$3` will contain the *multi-word* string (including the whitespace), but it will not include quotes. Your script as it sits is not wrong. (aside from quoting) If `$3` is filled after the `$2` test succeeds, you can use your `$3`. Make sure *You* quote `"$3"` where required. (like in `[ -z "$3" ]`)... (In fact you have your quoting requirements *backwards*. They are *not* required in `[[ ... ]]` but *are* required with `[ ... ]`) – David C. Rankin Jun 30 '18 at 06:20

1 Answers1

2

Continuing from the comment, what happens on the command line regarding the arguments to your script is handled by your shell. So when you provide command line arguments the normal shell expansions and word-splitting apply. When you quote arguments to your script, your shell will properly avoid word-splitting within quotes, but the actual quotation marks themselves will be removed by your shell.

Within your script, your positional parameters will properly contain the results of your shell's handling of the arguments. So in your case, your script (or git in your example) will receive,

$1 : commit
$2 : -m 
$3 : your message as a sentence

Your script logic is fine, the problem your are running into in your script is improper quoting. Specifically [[ ... ]] does not require quoting, but [ ... ] does.

Since you do not quote $3 in [ -z $3 ] you effectively are asking:

[ -z your message as a sentence ]

which the shell will take as too many arguments. So to remedy the problem, quote when using test or [ ... ] (which are synonymous), e.g.

[ -z "$3" ]

Looks things over and let me know if you have further questions.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • Thank you, definitely I needed it to quote `"$3"` – Abraham Jun 30 '18 at 06:38
  • Sure, it happens to everybody when they start learning scripting. You can never go wrong if you always quote your variables (you can learn the exceptions to that rule as you progress along) Good luck with your scripting. – David C. Rankin Jun 30 '18 at 06:39
  • @CarlosAbraham I recommend running your scripts through [shellcheck.net](https://www.shellcheck.net) -- shell syntax has a lot of gotchas like this, and shellcheck is good at pointing out the common ones. – Gordon Davisson Jun 30 '18 at 08:02