Skip to main content
Stack Overflow
  1. About
  2. For Teams

Return to Answer

Post Timeline

clarify what request/feature rules out which solution
Source Link
Robert Siemer
  • 35.2k
  • 11
  • 89
  • 101
  • Use enhanced getopt from util-linux or formerly GNU glibc.1
  • It works with getopt_long() the C function of GNU glibc.
  • no other solution on this page can do all this:
    • handles spaces, quoting characters and even binary in arguments2 (nonthis rules non-enhanced getopt can’t do thisout)
    • it can handle options at the end: script.sh -o outFile file1 file2 -v (this rules getopts doesn’t do thisout)
    • allows =-style long options: script.sh --outfile=fileOut --infile fileIn (allowing both isat the same time makes it really lengthy ifwhen self parsing)
    • allows combined short options, e.g. -vfd (real work iftogether with the one before this practically rules out self parsing)
    • allows touching option-arguments, e.g. -oOutfile or -vfdoOutfile (you still want to program it yourself?)
  • Is so old already3 that it comes preinstalled on any GNU system (i.e. Linux mostly); see footnote1
  • You can test for its existence with: getopt --test → return value 4.
  • Other getopt or shell-builtin getopts are of limited use.
  • Use enhanced getopt from util-linux or formerly GNU glibc.1
  • It works with getopt_long() the C function of GNU glibc.
  • no other solution on this page can do all this:
    • handles spaces, quoting characters and even binary in arguments2 (non-enhanced getopt can’t do this)
    • it can handle options at the end: script.sh -o outFile file1 file2 -v (getopts doesn’t do this)
    • allows =-style long options: script.sh --outfile=fileOut --infile fileIn (allowing both is lengthy if self parsing)
    • allows combined short options, e.g. -vfd (real work if self parsing)
    • allows touching option-arguments, e.g. -oOutfile or -vfdoOutfile
  • Is so old already3 that it comes preinstalled on any GNU system (i.e. Linux mostly); see footnote1
  • You can test for its existence with: getopt --test → return value 4.
  • Other getopt or shell-builtin getopts are of limited use.
  • Use enhanced getopt from util-linux or formerly GNU glibc.1
  • It works with getopt_long() the C function of GNU glibc.
  • no other solution on this page can do all this:
    • handles spaces, quoting characters and even binary in arguments2 (this rules non-enhanced getopt out)
    • it can handle options at the end: script.sh -o outFile file1 file2 -v (this rules getopts out)
    • allows =-style long options: script.sh --outfile=fileOut --infile fileIn (allowing both at the same time makes it really lengthy when self parsing)
    • allows combined short options, e.g. -vfd (together with the one before this practically rules out self parsing)
    • allows touching option-arguments, e.g. -oOutfile or -vfdoOutfile (you still want to program it yourself?)
  • Is so old already3 that it comes preinstalled on any GNU system (i.e. Linux mostly); see footnote1
  • You can test for its existence with: getopt --test → return value 4.
  • Other getopt or shell-builtin getopts are of limited use.
#!/bin/bash
# More safety, by turning some bugs into errors.
set -o errexit -o pipefail -o noclobber -o nounset
# ignore errexit with `&& true`
getopt --test > /dev/null && true
if [[ $? -ne 4 ]]; then
 echo 'I’m sorry, `getopt --test` failed in this environment.'
 exit 1
fi
# option --output/-o requires 1 argument
LONGOPTS=debug,force,output:,verbose
OPTIONS=dfo:v
# -temporarily store output to be able to check for errors
# -activate quoting/enhanced mode (e.g. by writing out "--options")
# -pass arguments only via -- "$@" to separate them correctly
# -if getopt fails, it complains itself to stdoutstderr
PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTS --name "0ドル" -- "$@") || exit 2
# read getopt’s output this way to handle the quoting right:
eval set -- "$PARSED"
d=n f=n v=n outFile=-
# now enjoy the options in order and nicely split until we see --
while true; do
 case "1ドル" in
 -d|--debug)
 d=y
 shift
 ;;
 -f|--force)
 f=y
 shift
 ;;
 -v|--verbose)
 v=y
 shift
 ;;
 -o|--output)
 outFile="2ドル"
 shift 2
 ;;
 --)
 shift
 break
 ;;
 *)
 echo "Programming error"
 exit 3
 ;;
 esac
done
# handle non-option arguments
if [[ $# -ne 1 ]]; then
 echo "0ドル: A single input file is required."
 exit 4
fi
echo "verbose: $v, force: $f, debug: $d, in: 1,ドル out: $outFile"
#!/bin/bash
# More safety, by turning some bugs into errors.
set -o errexit -o pipefail -o noclobber -o nounset
# ignore errexit with `&& true`
getopt --test > /dev/null && true
if [[ $? -ne 4 ]]; then
 echo 'I’m sorry, `getopt --test` failed in this environment.'
 exit 1
fi
# option --output/-o requires 1 argument
LONGOPTS=debug,force,output:,verbose
OPTIONS=dfo:v
# -temporarily store output to be able to check for errors
# -activate quoting/enhanced mode (e.g. by writing out "--options")
# -pass arguments only via -- "$@" to separate them correctly
# -if getopt fails, it complains itself to stdout
PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTS --name "0ドル" -- "$@") || exit 2
# read getopt’s output this way to handle the quoting right:
eval set -- "$PARSED"
d=n f=n v=n outFile=-
# now enjoy the options in order and nicely split until we see --
while true; do
 case "1ドル" in
 -d|--debug)
 d=y
 shift
 ;;
 -f|--force)
 f=y
 shift
 ;;
 -v|--verbose)
 v=y
 shift
 ;;
 -o|--output)
 outFile="2ドル"
 shift 2
 ;;
 --)
 shift
 break
 ;;
 *)
 echo "Programming error"
 exit 3
 ;;
 esac
done
# handle non-option arguments
if [[ $# -ne 1 ]]; then
 echo "0ドル: A single input file is required."
 exit 4
fi
echo "verbose: $v, force: $f, debug: $d, in: 1,ドル out: $outFile"
#!/bin/bash
# More safety, by turning some bugs into errors.
set -o errexit -o pipefail -o noclobber -o nounset
# ignore errexit with `&& true`
getopt --test > /dev/null && true
if [[ $? -ne 4 ]]; then
 echo 'I’m sorry, `getopt --test` failed in this environment.'
 exit 1
fi
# option --output/-o requires 1 argument
LONGOPTS=debug,force,output:,verbose
OPTIONS=dfo:v
# -temporarily store output to be able to check for errors
# -activate quoting/enhanced mode (e.g. by writing out "--options")
# -pass arguments only via -- "$@" to separate them correctly
# -if getopt fails, it complains itself to stderr
PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTS --name "0ドル" -- "$@") || exit 2
# read getopt’s output this way to handle the quoting right:
eval set -- "$PARSED"
d=n f=n v=n outFile=-
# now enjoy the options in order and nicely split until we see --
while true; do
 case "1ドル" in
 -d|--debug)
 d=y
 shift
 ;;
 -f|--force)
 f=y
 shift
 ;;
 -v|--verbose)
 v=y
 shift
 ;;
 -o|--output)
 outFile="2ドル"
 shift 2
 ;;
 --)
 shift
 break
 ;;
 *)
 echo "Programming error"
 exit 3
 ;;
 esac
done
# handle non-option arguments
if [[ $# -ne 1 ]]; then
 echo "0ドル: A single input file is required."
 exit 4
fi
echo "verbose: $v, force: $f, debug: $d, in: 1,ドル out: $outFile"
replaced PIPESTATUS and ! with equivalent but cleaner || and &&
Source Link
Robert Siemer
  • 35.2k
  • 11
  • 89
  • 101
#!/bin/bash
# More safety, by turning some bugs into errors.
# Without `errexit` you don’t need ! and can replace
# ${PIPESTATUS[0]} with a simple $?, but I prefer safety.
set -o errexit -o pipefail -o noclobber -o nounset
# -allow a command to fail with !’s side effect onignore errexit
# -use return value from ${PIPESTATUS[0]}, because !with hosed`&& $?true`
! getopt --test > /dev/null && true
if [[ ${PIPESTATUS[0]}? -ne 4 ]]; then
 echo 'I’m sorry, `getopt --test` failed in this environment.'
 exit 1
fi
# option --output/-o requires 1 argument
LONGOPTS=debug,force,output:,verbose
OPTIONS=dfo:v
# -regarding ! and PIPESTATUS see above
# -temporarily store output to be able to check for errors
# -activate quoting/enhanced mode (e.g. by writing out "--options")
# -pass arguments only via -- "$@" to separate them correctly
!# -if getopt fails, it complains itself to stdout
PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTS --name "0ドル" -- "$@")
if [[ ${PIPESTATUS[0]} -ne 0 ]]; then
 # e.g. return value is 1
 # then getopt has complained about wrong arguments to stdout
 || exit 2
fi
# read getopt’s output this way to handle the quoting right:
eval set -- "$PARSED"
d=n f=n v=n outFile=-
# now enjoy the options in order and nicely split until we see --
while true; do
 case "1ドル" in
 -d|--debug)
 d=y
 shift
 ;;
 -f|--force)
 f=y
 shift
 ;;
 -v|--verbose)
 v=y
 shift
 ;;
 -o|--output)
 outFile="2ドル"
 shift 2
 ;;
 --)
 shift
 break
 ;;
 *)
 echo "Programming error"
 exit 3
 ;;
 esac
done
# handle non-option arguments
if [[ $# -ne 1 ]]; then
 echo "0ドル: A single input file is required."
 exit 4
fi
echo "verbose: $v, force: $f, debug: $d, in: 1,ドル out: $outFile"
#!/bin/bash
# More safety, by turning some bugs into errors.
# Without `errexit` you don’t need ! and can replace
# ${PIPESTATUS[0]} with a simple $?, but I prefer safety.
set -o errexit -o pipefail -o noclobber -o nounset
# -allow a command to fail with !’s side effect on errexit
# -use return value from ${PIPESTATUS[0]}, because ! hosed $?
! getopt --test > /dev/null 
if [[ ${PIPESTATUS[0]} -ne 4 ]]; then
 echo 'I’m sorry, `getopt --test` failed in this environment.'
 exit 1
fi
# option --output/-o requires 1 argument
LONGOPTS=debug,force,output:,verbose
OPTIONS=dfo:v
# -regarding ! and PIPESTATUS see above
# -temporarily store output to be able to check for errors
# -activate quoting/enhanced mode (e.g. by writing out "--options")
# -pass arguments only via -- "$@" to separate them correctly
! PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTS --name "0ドル" -- "$@")
if [[ ${PIPESTATUS[0]} -ne 0 ]]; then
 # e.g. return value is 1
 # then getopt has complained about wrong arguments to stdout
  exit 2
fi
# read getopt’s output this way to handle the quoting right:
eval set -- "$PARSED"
d=n f=n v=n outFile=-
# now enjoy the options in order and nicely split until we see --
while true; do
 case "1ドル" in
 -d|--debug)
 d=y
 shift
 ;;
 -f|--force)
 f=y
 shift
 ;;
 -v|--verbose)
 v=y
 shift
 ;;
 -o|--output)
 outFile="2ドル"
 shift 2
 ;;
 --)
 shift
 break
 ;;
 *)
 echo "Programming error"
 exit 3
 ;;
 esac
done
# handle non-option arguments
if [[ $# -ne 1 ]]; then
 echo "0ドル: A single input file is required."
 exit 4
fi
echo "verbose: $v, force: $f, debug: $d, in: 1,ドル out: $outFile"
#!/bin/bash
# More safety, by turning some bugs into errors.
set -o errexit -o pipefail -o noclobber -o nounset
# ignore errexit with `&& true`
getopt --test > /dev/null && true
if [[ $? -ne 4 ]]; then
 echo 'I’m sorry, `getopt --test` failed in this environment.'
 exit 1
fi
# option --output/-o requires 1 argument
LONGOPTS=debug,force,output:,verbose
OPTIONS=dfo:v
# -temporarily store output to be able to check for errors
# -activate quoting/enhanced mode (e.g. by writing out "--options")
# -pass arguments only via -- "$@" to separate them correctly
# -if getopt fails, it complains itself to stdout
PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTS --name "0ドル" -- "$@") || exit 2
# read getopt’s output this way to handle the quoting right:
eval set -- "$PARSED"
d=n f=n v=n outFile=-
# now enjoy the options in order and nicely split until we see --
while true; do
 case "1ドル" in
 -d|--debug)
 d=y
 shift
 ;;
 -f|--force)
 f=y
 shift
 ;;
 -v|--verbose)
 v=y
 shift
 ;;
 -o|--output)
 outFile="2ドル"
 shift 2
 ;;
 --)
 shift
 break
 ;;
 *)
 echo "Programming error"
 exit 3
 ;;
 esac
done
# handle non-option arguments
if [[ $# -ne 1 ]]; then
 echo "0ドル: A single input file is required."
 exit 4
fi
echo "verbose: $v, force: $f, debug: $d, in: 1,ドル out: $outFile"
Rollback to Revision 47
Source Link
Robert Siemer
  • 35.2k
  • 11
  • 89
  • 101
Loading
Make the answer to be an answer, not a criticism of other answers. Make the text clearer.
Source Link
VasiliNovikov
  • 10.5k
  • 5
  • 53
  • 65
Loading
rectifying defacing edit: OS X stays in the footnote exclusively, links have the same style incl. in markdown, do not spread OS X install instructions in multiple places, the preinstalled advantage does not apply to OS X either
Source Link
Robert Siemer
  • 35.2k
  • 11
  • 89
  • 101
Loading
adding https://formulae.brew.sh/formula/util-linux to appropriate footnote area
Source Link
Johnny Utahh
  • 2.5k
  • 3
  • 29
  • 46
Loading
sharing which macOS Homebrew package has a working (proper?) getopt
Source Link
Johnny Utahh
  • 2.5k
  • 3
  • 29
  • 46
Loading
copyedit
Source Link
Robert Siemer
  • 35.2k
  • 11
  • 89
  • 101
Loading
added 40 characters in body
Source Link
Daniel Kaplan
  • 68.5k
  • 60
  • 274
  • 414
Loading
reinstate and improve _how_ this answer compares to the others and _why_ it is better
Source Link
Robert Siemer
  • 35.2k
  • 11
  • 89
  • 101
Loading
Rollback to Revision 39
Source Link
Robert Siemer
  • 35.2k
  • 11
  • 89
  • 101
Loading
removed unnecessary header
Source Link
Inanc Gumus
  • 28.3k
  • 10
  • 89
  • 104
Loading
improve comparison with top-voted answer
Source Link
Robert Siemer
  • 35.2k
  • 11
  • 89
  • 101
Loading
improve comparison with top-voted answer
Source Link
Robert Siemer
  • 35.2k
  • 11
  • 89
  • 101
Loading
improving comments
Source Link
Robert Siemer
  • 35.2k
  • 11
  • 89
  • 101
Loading
rendered backticks safe in string
Source Link
Robert Siemer
  • 35.2k
  • 11
  • 89
  • 101
Loading
added 30 characters in body
Source Link
BallpointBen
  • 15.7k
  • 2
  • 46
  • 81
Loading
improve script by including errexit and fixing bugs detected by that option
Source Link
Robert Siemer
  • 35.2k
  • 11
  • 89
  • 101
Loading
improve script comment
Source Link
Robert Siemer
  • 35.2k
  • 11
  • 89
  • 101
Loading
improve script comment
Source Link
Robert Siemer
  • 35.2k
  • 11
  • 89
  • 101
Loading
copyediting
Source Link
Robert Siemer
  • 35.2k
  • 11
  • 89
  • 101
Loading
included hint for OS X on how to post-install enhanced getopt
Source Link
Robert Siemer
  • 35.2k
  • 11
  • 89
  • 101
Loading
add equal-sign for option arguments for clarity (that the option eats an argument)
Source Link
Robert Siemer
  • 35.2k
  • 11
  • 89
  • 101
Loading
Rollback to Revision 26
Source Link
Robert Siemer
  • 35.2k
  • 11
  • 89
  • 101
Loading
1
2 3
lang-bash

AltStyle によって変換されたページ (->オリジナル) /