-1

I am doing printf '%s\n' "$@" and calling the function using

pfm "-d DIR" "--directory=DIR"

I get errors, namely:

bash: invalid option -- 'd'
bash: invalid option -- ' '
bash: invalid option -- 'D'
bash: invalid option -- 'I'
bash: invalid option -- 'R'
bash: unrecognized option '--directory=DIR'

Here is the relevant code

printfm ()
{
  # Process command line options
  shortopts="hVw::"
  longopts="help,version,warning:"

  opts=$(getopt -o "$shortopts" -l "$longopts"  \
        -n "$(basename $0)" -- "$@")
  if [ $? -eq 0 ]; then
    eval "set -- ${opts}"
    while [ $# -gt 0 ]; do
      case "$1" in
        -V|version)
          printf "V01 Jul 2021 Wk27"
          printf ""
          ;;
        -h|-\?|--help)
          help=1
          printf "Prints two text strings on two lines.\n"
          printf "\$@ TEXT  Sentences to print en new lines.\n"
          shift
      local -r f=0
      break
      ;;
          # ......................................................
        -w|--warning)
      case "$2" in
             "1") local -r warn="first";  shift 2  ;;
             *)   local -r warn="all";    shift 2  ;;
          esac
      local -r f=1
      ;;
        --)
          shift;  break  ;;
      esac
    done
  else
    shorthelp=1 # getopt returned (and reported) an error.
  fi

  red=$(tput setaf 9)  
  rgl=$(tput sgr0)

  local f=1
  if (( f == 1 )); then

    # print normal multi-line text
    [[ ! -z warn ]] && printf '%s\n' "$@"

    # print multi-line warnings
    if [[ -n warn && "$warn" == "first" ]]; then
      printf '%s\n' ${red}"$1"${rgl}  # first line red
      printf '%s\n' "${@:2}"          # remaining, uncoloured
    elif [[ -n warn && "$warn" == "all" ]]; then
      printf '%s\n' ${red}"$@"${rgl}  # all lines red
    fi

  fi
  return 0
}

alias pfm=printfm 
Pietru
  • 371
  • 1
  • 14
  • 4
    What is `pfm?`.. – Arkadiusz Drabczyk Jul 22 '21 at 12:18
  • 3
    I can't reproduce what you are seeing. The statement `printf '%s\n' "-d DIR" "--directory=DIR"` prints the two arguments as expected. Please consider showing your actual implementation of the `pfm` function. If `printf` had been an issue, then the error would have mentioned the `printf` utility by name, instead it looks as if it's the actual shell complaining. – Kusalananda Jul 22 '21 at 12:24
  • Does `pfm -- "-d DIR" "--directory=DIR"` do what you want? You have explicitly coded the bit that ignores options after `--` after all... – Kusalananda Jul 22 '21 at 13:43
  • `pfm -- "-d DIR" "--directory=DIR"` does work when using `--`. But `pfm "-d DIR" "--directory=DIR"`. What do you think about the implementation, is it weird or improved a little bit? What do you think of the `--` option? – Pietru Jul 22 '21 at 14:29
  • Using `--` is the common way to delimit the actual options from other non-option arguments (see [here](https://unix.stackexchange.com/questions/570729/where-is-the-double-dash-argument-documented)). You must have known about this as your code correctly handle `--` as a way of signaling that there is no more options among the arguments to `printfm`. I don't quite understand wy you don't want to use `--` in front of your arguments that are clearly _not_ options to the `printfm` function. – Kusalananda Jul 22 '21 at 14:43
  • Shall use `--` as you say. Thanks. – Pietru Jul 22 '21 at 15:00

1 Answers1

3

There is no issue involving printf here.

Your printfm function takes arguments and does its own option parsing. The options that it takes are -V, -h, -?, -w, --warning, and --help (note that --version will be recognized, but can't be acted upon as there is a typo, a missing -- in front of version, in the case statement). When you call it with the two arguments -d DIR and --directory=DIR, the getopt utility will complain that the strings contain unknown options.

The common way of passing non-option arguments, that look like options, to a utility or function, is to delimit the actual options from the non-option arguments using -- ("double dash"):

printfm -- "-d DIR" "--directory=DIR"

This is correctly handled by your printfm code, will cause the option parsing to stop at the --, and will allow you to receive the two strings as non-option arguments, even though they start with a dash.

Related:

Kusalananda
  • 320,670
  • 36
  • 633
  • 936