Bug 215207 - [patch] getopt(1) example mangles command-line arguments with embedded spaces
Summary: [patch] getopt(1) example mangles command-line arguments with embedded spaces
Status: Closed Not Accepted
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Many People
Assignee: freebsd-bugs (Nobody)
URL:
Keywords: patch
Depends on:
Blocks:
 
Reported: 2016-12-11 08:35 UTC by Diomidis Spinellis
Modified: 2018-05-23 13:21 UTC (History)
1 user (show)

See Also:


Attachments
Proposed fix (460 bytes, patch)
2016-12-11 08:35 UTC, Diomidis Spinellis
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Diomidis Spinellis freebsd_committer freebsd_triage 2016-12-11 08:35:09 UTC
Created attachment 177862 [details]
Proposed fix

The provided getopt(1) example in the manual page mangles command-line arguments containing spaces by splitting them through IFS.

Consider the following minimal example script, written by following the man page example.

#!/bin/sh
args=`getopt a: $*`
if [ $? -ne 0 ]; then
   echo 'Error'
   exit 2
fi

set -- $args
while :; do
   case "$1" in
   -a)
           flags=-a
           shift
           ;;
   --)
           shift; break
           ;;
   esac
done

for i; do
    echo "Arg $i"
    shift
done

When the above script is run with 'a b' as an argument, it will output
Arg a
Arg b
rather than
Arg a b

The problem can be fixed by applying the attached patch.  Note that the patch does not address option arguments with embedded spaces.
Comment 1 Jilles Tjoelker freebsd_committer freebsd_triage 2016-12-24 22:55:48 UTC
The patched version ignores getopt(1)'s output except for the number of iterations of a loop. This drops necessary adjustments made by getopt(1) such as changing -ab to -a -b.

As noted in the BUGS section of getopt(1), fixing arguments with whitespace and shell metacharacters is hard. With the current API, it is not possible.

A reasonable solution for shell scripts is to use the getopts builtin instead of getopt(1). This fixes the problems with special characters and poor error messages and simplifies the code in the script. The man page could recommend this more.

If you insist on using something called "getopt" or want to use long options, an alternative is to use a non-standard mode of the misc/getopt port.
Comment 2 Eitan Adler freebsd_committer freebsd_triage 2018-05-23 13:21:47 UTC
per jilles.