I always try to simplify a command line parser implementation regardless any programming language: C++, bash, ... To do that, I restrict the command line option to a regular form only. All my arguments should be
form. Even I want to specify a file name, my program needs an argument key, e.g., '-in_file input_filename. If you do in this way, each command line argument has the key, so I can put all the command line options to a map. This makes the command line parser simple. I usually don't need getopt library. Also I try to simplify the command line option support, means smaller number of command line options, and use a config file, which contains 'key = value' lines. This has two advantages: you can support negative values without confusing the command line option, easy to reproduce the test case.
However, this method still has a problem when the command line option includes white space. If I could, I will only try to use config files, but, in practice, it is not always the solution.
Let me show you such command line options. For instance, I want to pass a vector to my command as the following.
'-arg_key value'
form. Even I want to specify a file name, my program needs an argument key, e.g., '-in_file input_filename. If you do in this way, each command line argument has the key, so I can put all the command line options to a map. This makes the command line parser simple. I usually don't need getopt library. Also I try to simplify the command line option support, means smaller number of command line options, and use a config file, which contains 'key = value' lines. This has two advantages: you can support negative values without confusing the command line option, easy to reproduce the test case.
However, this method still has a problem when the command line option includes white space. If I could, I will only try to use config files, but, in practice, it is not always the solution.
Let me show you such command line options. For instance, I want to pass a vector to my command as the following.
command -eye_position '0 0 -10' -up_vector '0 1 0'If I run a executable by hand from a shell, this is fine, but I usually want to run a command from a shell script like for automated tests. Here is an implementation example. test_1.sh:
-- test_1.sh -- echo "call with two args, but the second one has spaces." echo "./test_2.sh args0 'args1_1 args1_2 args1_3'" ./test_2.sh args0 'args1_1 args1_2 args1_3' -- test_1.sh --The script test_2.sh just shows how the commend line options are passed.
-- test_2.sh -- echo "show the args with \$*." for i in $* do echo " $i" done echo "show the args with quoted \"\$*\"." for i in "$*" do echo " $i" done echo "show the args with \$@." for i in $@ do echo " $i" done echo "show the args with quoted \"\$@\"." for i in "$@" do echo " $i" done -- test_2.sh --What I want to get in the \verb|test_2.sh| is two arguments as the following:
- $1: args0
- $2: args1_1 args1_2 args1_3
-- result -- call with two args, but the second one has spaces. ./test_2.sh args0 'args1_1 args1_2 args1_3' show the args with $*. args0 args1_1 args1_2 args1_3 show the args with quoted "$*". args0 args1_1 args1_2 args1_3 show the args with $@. args0 args1_1 args1_2 args1_3 show the args with quoted "$@". args0 args1_1 args1_2 args1_3 -- result --If I use $* or $@ only, the white space separates the second argument, and made four arguments. To prevent this, I quote the arguments in the script,but "$*" becomes now only one argument. The "$@" is the one I wanted. This is the difference between $* and $@ of bash. This is a detail, and not necessary to know about it I Think. However, if you know it, you are a bit happier than before, I wish.
Comments