Merge commit 'b5d57fc87925cb3c029de19d0a94de5ca07ae28e'
[sliver-openvswitch.git] / utilities / ovs-ctl.in
1 #! /bin/sh
2 # Copyright (C) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 case $0 in
17     */*) dir0=`echo "$0" | sed 's,/[^/]*$,,'` ;;
18     *) dir0=./ ;;
19 esac
20 . "$dir0/ovs-lib" || exit 1
21
22 for dir in "$sbindir" "$bindir" /sbin /bin /usr/sbin /usr/bin; do
23     case :$PATH: in
24         *:$dir:*) ;;
25         *) PATH=$PATH:$dir ;;
26     esac
27 done
28
29 ## ----- ##
30 ## start ##
31 ## ----- ##
32
33 insert_mod_if_required () {
34     # If openvswitch is already loaded then we're done.
35     test -e /sys/module/openvswitch -o -e /sys/module/openvswitch_mod && \
36      return 0
37
38     # Load openvswitch.  If that's successful then we're done.
39     action "Inserting openvswitch module" modprobe openvswitch && return 0
40
41     # If the bridge module is loaded, then that might be blocking
42     # openvswitch.  Try to unload it, if there are no bridges.
43     test -e /sys/module/bridge || return 1
44     bridges=`echo /sys/class/net/*/bridge | sed 's,/sys/class/net/,,g;s,/bridge,,g'`
45     if test "$bridges" != "*"; then
46         log_warning_msg "not removing bridge module because bridges exist ($bridges)"
47         return 1
48     fi
49     action "removing bridge module" rmmod bridge || return 1
50
51     # Try loading openvswitch again.
52     action "Inserting openvswitch module" modprobe openvswitch
53 }
54
55 ovs_vsctl () {
56     ovs-vsctl --no-wait "$@"
57 }
58
59 ovsdb_tool () {
60     ovsdb-tool -vconsole:off "$@"
61 }
62
63 create_db () {
64     action "Creating empty database $DB_FILE" ovsdb_tool create "$DB_FILE" "$DB_SCHEMA"
65 }
66
67 upgrade_db () {
68     schemaver=`ovsdb_tool schema-version "$DB_SCHEMA"`
69     if test ! -e "$DB_FILE"; then
70         log_warning_msg "$DB_FILE does not exist"
71         install -d -m 755 -o root -g root `dirname $DB_FILE`
72         create_db
73     elif test X"`ovsdb_tool needs-conversion "$DB_FILE" "$DB_SCHEMA"`" != Xno; then
74         # Back up the old version.
75         version=`ovsdb_tool db-version "$DB_FILE"`
76         cksum=`ovsdb_tool db-cksum "$DB_FILE" | awk '{print $1}'`
77         backup=$DB_FILE.backup$version-$cksum
78         action "Backing up database to $backup" cp "$DB_FILE" "$backup" || return 1
79
80         # Compact database.  This is important if the old schema did not enable
81         # garbage collection (i.e. if it did not have any tables with "isRoot":
82         # true) but the new schema does.  In that situation the old database
83         # may contain a transaction that creates a record followed by a
84         # transaction that creates the first use of the record.  Replaying that
85         # series of transactions against the new database schema (as "convert"
86         # does) would cause the record to be dropped by the first transaction,
87         # then the second transaction would cause a referential integrity
88         # failure (for a strong reference).
89         #
90         # Errors might occur on an Open vSwitch downgrade if ovsdb-tool doesn't
91         # understand some feature of the schema used in the OVSDB version that
92         # we're downgrading from, so we don't give up on error.
93         action "Compacting database" ovsdb_tool compact "$DB_FILE"
94
95         # Upgrade or downgrade schema.
96         if action "Converting database schema" ovsdb_tool convert "$DB_FILE" "$DB_SCHEMA"; then
97             :
98         else
99             log_warning_msg "Schema conversion failed, using empty database instead"
100             rm -f "$DB_FILE"
101             create_db
102         fi
103     fi
104 }
105
106 set_system_ids () {
107     set ovs_vsctl set Open_vSwitch .
108
109     OVS_VERSION=`ovs-vswitchd --version | sed 's/.*) //;1q'`
110     set "$@" ovs-version="$OVS_VERSION"
111
112     case $SYSTEM_ID in
113         random)
114             id_file=$etcdir/system-id.conf
115             uuid_file=$etcdir/install_uuid.conf
116             if test -e "$id_file"; then
117                 SYSTEM_ID=`cat "$id_file"`
118             elif test -e "$uuid_file"; then
119                 # Migrate from old file name.
120                 . "$uuid_file"
121                 SYSTEM_ID=$INSTALLATION_UUID
122                 echo "$SYSTEM_ID" > "$id_file"
123             elif SYSTEM_ID=`uuidgen`; then
124                 echo "$SYSTEM_ID" > "$id_file"
125             else
126                 log_failure_msg "missing uuidgen, could not generate system ID"
127             fi
128             ;;
129
130         '')
131             log_failure_msg "system ID not configured, please use --system-id"
132             ;;
133
134         *)
135             ;;
136     esac
137     set "$@" external-ids:system-id="\"$SYSTEM_ID\""
138
139     if test X"$SYSTEM_TYPE" != X; then
140         set "$@" system-type="\"$SYSTEM_TYPE\""
141     else
142         log_failure_msg "no default system type, please use --system-type"
143     fi
144
145     if test X"$SYSTEM_VERSION" != X; then
146         set "$@" system-version="\"$SYSTEM_VERSION\""
147     else
148         log_failure_msg "no default system version, please use --system-version"
149     fi
150
151     action "Configuring Open vSwitch system IDs" "$@" $extra_ids
152 }
153
154 check_force_cores () {
155     if test X"$FORCE_COREFILES" = Xyes; then
156         ulimit -c 67108864
157     fi
158 }
159
160 start_ovsdb () {
161     check_force_cores
162
163     if daemon_is_running ovsdb-server; then
164         log_success_msg "ovsdb-server is already running"
165     else
166         # Create initial database or upgrade database schema.
167         upgrade_db || return 1
168
169         # Start ovsdb-server.
170         set ovsdb-server "$DB_FILE"
171         for db in $EXTRA_DBS; do
172             case $db in
173                 /*) ;;
174                 *) db=$dbdir/$db ;;
175             esac
176
177             if test ! -f "$db"; then
178                 log_warning_msg "$db (from \$EXTRA_DBS) does not exist."
179             elif ovsdb-tool db-version "$db" >/dev/null; then
180                 set "$@" "$db"
181             else
182                 log_warning_msg "$db (from \$EXTRA_DBS) cannot be read as a database (see error message above)"
183             fi
184         done
185         set "$@" -vconsole:emer -vsyslog:err -vfile:info
186         set "$@" --remote=punix:"$DB_SOCK"
187         set "$@" --private-key=db:Open_vSwitch,SSL,private_key
188         set "$@" --certificate=db:Open_vSwitch,SSL,certificate
189         set "$@" --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert
190         start_daemon "$OVSDB_SERVER_PRIORITY" "$OVSDB_SERVER_WRAPPER" "$@" \
191             || return 1
192
193         # Initialize database settings.
194         ovs_vsctl -- init -- set Open_vSwitch . db-version="$schemaver" \
195             || return 1
196         set_system_ids || return 1
197         if test X"$DELETE_BRIDGES" = Xyes; then
198             for bridge in `ovs_vsctl list-br`; do
199         ovs_vsctl del-br $bridge
200             done
201         fi
202     fi
203 }
204
205 start_forwarding () {
206     check_force_cores
207
208     insert_mod_if_required || return 1
209
210     if daemon_is_running ovs-vswitchd; then
211         log_success_msg "ovs-vswitchd is already running"
212     else
213         # Increase the limit on the number of open file descriptors.
214         # On Linux, ovs-vswitchd needs about one file descriptor per
215         # switch port, so this allows a very large number of switch
216         # ports.
217         ulimit -n 5000
218
219             # Start ovs-vswitchd.
220             set ovs-vswitchd unix:"$DB_SOCK"
221             set "$@" -vconsole:emer -vsyslog:err -vfile:info
222             if test X"$MLOCKALL" != Xno; then
223                 set "$@" --mlockall
224             fi
225             start_daemon "$OVS_VSWITCHD_PRIORITY" "$OVS_VSWITCHD_WRAPPER" "$@"
226     fi
227
228     # Now that ovs-vswitchd has started and completed its initial
229     # configuration, tell ovsdb-server to conenct to the remote managers.  We
230     # used to do this at ovsdb-server startup time, but waiting for
231     # ovs-vswitchd to finish configuring means that remote managers see less
232     # churn in the database at startup or restart.  (For example, managers
233     # won't briefly see empty datapath-id or ofport columns for records that
234     # exist at startup.)
235     action "Enabling remote OVSDB managers" \
236         ovs-appctl -t ovsdb-server ovsdb-server/add-remote \
237             db:Open_vSwitch,Open_vSwitch,manager_options
238 }
239
240 ## ---- ##
241 ## stop ##
242 ## ---- ##
243
244 stop_ovsdb () {
245     stop_daemon ovsdb-server
246 }
247
248 stop_forwarding () {
249     stop_daemon ovs-vswitchd
250 }
251
252 ## ----------------- ##
253 ## force-reload-kmod ##
254 ## ----------------- ##
255
256 internal_interfaces () {
257     # Outputs a list of internal interfaces:
258     #
259     #   - There is an internal interface for every bridge, whether it
260     #     has an Interface record or not and whether the Interface
261     #     record's 'type' is properly set or not.
262     #
263     #   - There is an internal interface for each Interface record whose
264     #     'type' is 'internal'.
265     #
266     # But ignore interfaces that don't really exist.
267     for d in `(ovs_vsctl --bare \
268                 -- --columns=name find Interface type=internal \
269                     -- list-br) | sort -u`
270     do
271         if test -e "/sys/class/net/$d"; then
272                 printf "%s " "$d"
273             fi
274     done
275 }
276
277 ovs_save () {
278     bridges=`ovs_vsctl -- --real list-br`
279     if [ -n "${bridges}" ] && \
280         "$datadir/scripts/ovs-save" "$1" ${bridges} > "$2"; then
281         chmod +x "$2"
282         return 0
283     fi
284     [ -z "${bridges}" ] && return 0
285 }
286
287 save_ofports_if_required () {
288     # Save ofports if we are upgrading from a pre-1.10 branch.
289     case `ovs-appctl version | sed 1q` in
290         "ovs-vswitchd (Open vSwitch) 1."[0-9].*)
291             action "Saving ofport values" ovs_save save-ofports \
292                 "${script_ofports}"
293             ;;
294     esac
295 }
296
297 save_interfaces () {
298     "$datadir/scripts/ovs-save" save-interfaces ${ifaces} \
299         > "${script_interfaces}"
300 }
301
302 restore_ofports () {
303     [ -x "${script_ofports}" ] && \
304         action "Restoring ofport values" "${script_ofports}"
305 }
306
307 restore_flows () {
308     [ -x "${script_flows}" ] && \
309         action "Restoring saved flows" "${script_flows}"
310 }
311
312 restore_interfaces () {
313     [ ! -x "${script_interfaces}" ] && return 0
314     action "Restoring interface configuration" "${script_interfaces}"
315     rc=$?
316     if test $rc = 0; then
317         level=debug
318     else
319         level=err
320     fi
321     log="logger -p daemon.$level -t ovs-save"
322     $log "interface restore script exited with status $rc:"
323     $log -f "$script_interfaces"
324 }
325
326 init_restore_scripts () {
327     script_interfaces=`mktemp`
328     script_flows=`mktemp`
329     script_ofports=`mktemp`
330     trap 'rm -f "${script_interfaces}" "${script_flows}" "${script_ofports}"' 0
331 }
332
333 force_reload_kmod () {
334     ifaces=`internal_interfaces`
335     action "Detected internal interfaces: $ifaces" true
336
337     init_restore_scripts
338
339     action "Saving flows" ovs_save save-flows "${script_flows}"
340
341     save_ofports_if_required
342
343     # Restart the database first, since a large database may take a
344     # while to load, and we want to minimize forwarding disruption.
345     stop_ovsdb
346     start_ovsdb
347
348     # Restore of ofports should happen before vswitchd is restarted.
349     restore_ofports
350
351     stop_forwarding
352
353     if action "Saving interface configuration" save_interfaces; then
354         :
355     else
356         log_warning_msg "Failed to save configuration, not replacing kernel module"
357         start_forwarding
358         exit 1
359     fi
360     chmod +x "$script_interfaces"
361
362     for dp in `ovs-dpctl dump-dps`; do
363         action "Removing datapath: $dp" ovs-dpctl del-dp "$dp"
364     done
365
366     # try both old and new names in case this is post upgrade
367     if test -e /sys/module/openvswitch_mod; then
368         action "Removing openvswitch module" rmmod openvswitch_mod
369     elif test -e /sys/module/openvswitch; then
370         action "Removing openvswitch module" rmmod openvswitch
371     fi
372
373     start_forwarding
374
375     restore_flows
376
377     restore_interfaces
378
379     "$datadir/scripts/ovs-check-dead-ifs"
380 }
381
382 ## ------- ##
383 ## restart ##
384 ## ------- ##
385
386 save_interfaces_if_required () {
387     # Save interfaces if we are upgrading from a pre-1.10 branch.
388     case `ovs-appctl version | sed 1q` in
389         "ovs-vswitchd (Open vSwitch) 1."[0-9].*)
390             ifaces=`internal_interfaces`
391             action "Detected internal interfaces: $ifaces" true
392             if action "Saving interface configuration" save_interfaces; then
393                 chmod +x "$script_interfaces"
394             fi
395             ;;
396     esac
397 }
398
399 restart () {
400     if daemon_is_running ovsdb-server && daemon_is_running ovs-vswitchd; then
401         init_restore_scripts
402         save_interfaces_if_required
403         action "Saving flows" ovs_save save-flows "${script_flows}"
404         save_ofports_if_required
405     fi
406
407     # Restart the database first, since a large database may take a
408     # while to load, and we want to minimize forwarding disruption.
409     stop_ovsdb
410     start_ovsdb
411
412     # Restore of ofports, if required, should happen before vswitchd is
413     # restarted.
414     restore_ofports
415
416     stop_forwarding
417     start_forwarding
418
419     # Restore the saved flows.
420     restore_flows
421
422     # Restore the interfaces if required. Return true even if restore fails.
423     restore_interfaces || true
424 }
425
426 ## --------------- ##
427 ## enable-protocol ##
428 ## --------------- ##
429
430 enable_protocol () {
431     # Translate the protocol name to a number, because "iptables -n -L" prints
432     # some protocols by name (despite the -n) and therefore we need to look for
433     # both forms.
434     #
435     # (iptables -S output is more uniform but old iptables doesn't have it.)
436     protonum=`grep "^$PROTOCOL[         ]" /etc/protocols | awk '{print $2}'`
437     if expr X"$protonum" : X'[0-9]\{1,\}$' > /dev/null; then :; else
438         log_failure_msg "unknown protocol $PROTOCOL"
439         return 1
440     fi
441
442     name=$PROTOCOL
443     match="(\$2 == \"$PROTOCOL\" || \$2 == $protonum)"
444     insert="iptables -I INPUT -p $PROTOCOL"
445     if test X"$DPORT" != X; then
446         name="$name to port $DPORT"
447         match="$match && /dpt:$DPORT/"
448         insert="$insert --dport $DPORT"
449     fi
450     if test X"$SPORT" != X; then
451         name="$name from port $SPORT"
452         match="$match && /spt:$SPORT/"
453         insert="$insert --sport $SPORT"
454     fi
455     insert="$insert -j ACCEPT"
456
457     if (iptables -n -L INPUT) >/dev/null 2>&1; then
458         if iptables -n -L INPUT | awk "$match { n++ } END { exit n == 0 }"
459         then
460             # There's already a rule for this protocol.  Don't override it.
461             log_success_msg "iptables already has a rule for $name, not explicitly enabling"
462         else
463             action "Enabling $name with iptables" $insert
464         fi
465     elif (iptables --version) >/dev/null 2>&1; then
466         action "cannot list iptables rules, not adding a rule for $name"
467     else
468         action "iptables binary not installed, not adding a rule for $name"
469     fi
470 }
471
472 ## ---- ##
473 ## main ##
474 ## ---- ##
475
476 set_defaults () {
477     SYSTEM_ID=
478
479     DELETE_BRIDGES=no
480
481     DAEMON_CWD=/
482     FORCE_COREFILES=yes
483     MLOCKALL=yes
484     OVSDB_SERVER_PRIORITY=-10
485     OVS_VSWITCHD_PRIORITY=-10
486     OVSDB_SERVER_WRAPPER=
487     OVS_VSWITCHD_WRAPPER=
488
489     DB_FILE=$dbdir/conf.db
490     DB_SOCK=$rundir/db.sock
491     DB_SCHEMA=$datadir/vswitch.ovsschema
492     EXTRA_DBS=
493
494     PROTOCOL=gre
495     DPORT=
496     SPORT=
497
498     type_file=$etcdir/system-type.conf
499     version_file=$etcdir/system-version.conf
500
501     if test -e "$type_file" ; then
502         SYSTEM_TYPE=`cat $type_file`
503         SYSTEM_VERSION=`cat $version_file`
504     elif (lsb_release --id) >/dev/null 2>&1; then
505         SYSTEM_TYPE=`lsb_release --id -s`
506         system_release=`lsb_release --release -s`
507         system_codename=`lsb_release --codename -s`
508         SYSTEM_VERSION="${system_release}-${system_codename}"
509     else
510         SYSTEM_TYPE=unknown
511         SYSTEM_VERSION=unknown
512     fi
513 }
514
515 usage () {
516     set_defaults
517     cat <<EOF
518 $0: controls Open vSwitch daemons
519 usage: $0 [OPTIONS] COMMAND
520
521 This program is intended to be invoked internally by Open vSwitch startup
522 scripts.  System administrators should not normally invoke it directly.
523
524 Commands:
525   start              start Open vSwitch daemons
526   stop               stop Open vSwitch daemons
527   restart            stop and start Open vSwitch daemons
528   status             check whether Open vSwitch daemons are running
529   version            print versions of Open vSwitch daemons
530   load-kmod          insert modules if not already present
531   force-reload-kmod  save OVS network device state, stop OVS, unload kernel
532                      module, reload kernel module, start OVS, restore state
533   enable-protocol    enable protocol specified in options with iptables
534   help               display this help message
535
536 One of the following options is required for "start", "restart" and "force-reload-kmod":
537   --system-id=UUID   set specific ID to uniquely identify this system
538   --system-id=random  use a random but persistent UUID to identify this system
539
540 Other important options for "start", "restart" and "force-reload-kmod":
541   --system-type=TYPE  set system type (e.g. "XenServer")
542   --system-version=VERSION  set system version (e.g. "5.6.100-39265p")
543   --external-id="key=value"
544                      add given key-value pair to Open_vSwitch external-ids
545   --delete-bridges   delete all bridges just before starting ovs-vswitchd
546
547 Less important options for "start", "restart" and "force-reload-kmod":
548   --daemon-cwd=DIR               set working dir for OVS daemons (default: $DAEMON_CWD)
549   --no-force-corefiles           do not force on core dumps for OVS daemons
550   --no-mlockall                  do not lock all of ovs-vswitchd into memory
551   --ovsdb-server-priority=NICE   set ovsdb-server's niceness (default: $OVSDB_SERVER_PRIORITY)
552   --ovs-vswitchd-priority=NICE   set ovs-vswitchd's niceness (default: $OVS_VSWITCHD_PRIORITY)
553
554 Debugging options for "start", "restart" and "force-reload-kmod":
555   --ovsdb-server-wrapper=WRAPPER
556   --ovs-vswitchd-wrapper=WRAPPER
557   --ovs-vswitchd-wrapper=WRAPPER
558      run specified daemon under WRAPPER (either 'valgrind' or 'strace')
559
560 File location options:
561   --db-file=FILE     database file name (default: $DB_FILE)
562   --db-sock=SOCKET   JSON-RPC socket name (default: $DB_SOCK)
563   --db-schema=FILE   database schema file name (default: $DB_SCHEMA)
564
565 Options for "enable-protocol":
566   --protocol=PROTOCOL  protocol to enable with iptables (default: gre)
567   --sport=PORT       source port to match (for tcp or udp protocol)
568   --dport=PORT       ddestination port to match (for tcp or udp protocol)
569
570 Other options:
571   -h, --help                  display this help message
572   -V, --version               display version information
573
574 Default directories with "configure" option and environment variable override:
575   logs: @LOGDIR@ (--with-logdir, OVS_LOGDIR)
576   pidfiles and sockets: @RUNDIR@ (--with-rundir, OVS_RUNDIR)
577   conf.db: @DBDIR@ (--with-dbdir, OVS_DBDIR)
578   system configuration: @sysconfdir@ (--sysconfdir, OVS_SYSCONFDIR)
579   data files: @pkgdatadir@ (--pkgdatadir, OVS_PKGDATADIR)
580   user binaries: @bindir@ (--bindir, OVS_BINDIR)
581   system binaries: @sbindir@ (--sbindir, OVS_SBINDIR)
582
583 Please report bugs to bugs@openvswitch.org (see REPORTING-BUGS for details).
584 EOF
585
586     exit 0
587 }
588
589 set_option () {
590     var=`echo "$option" | tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_`
591     eval set=\${$var+yes}
592     eval old_value=\$$var
593     if test X$set = X || \
594         (test $type = bool && \
595         test X"$old_value" != Xno && test X"$old_value" != Xyes); then
596         echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
597         return
598     fi
599     eval $var=\$value
600 }
601
602 daemons () {
603     echo ovsdb-server ovs-vswitchd
604 }
605
606 set_defaults
607 extra_ids=
608 command=
609 for arg
610 do
611     case $arg in
612         -h | --help)
613             usage
614             ;;
615         -V | --version)
616             echo "$0 (Open vSwitch) $VERSION"
617             exit 0
618             ;;
619         --external-id=*)
620             value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
621             case $value in
622                 *=*)
623                     extra_ids="$extra_ids external-ids:$value"
624                     ;;
625                 *)
626                     echo >&2 "$0: --external-id argument not in the form \"key=value\""
627                     exit 1
628                     ;;
629             esac
630             ;;
631         --[a-z]*=*)
632             option=`expr X"$arg" : 'X--\([^=]*\)'`
633             value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
634             type=string
635             set_option
636             ;;
637         --no-[a-z]*)
638             option=`expr X"$arg" : 'X--no-\(.*\)'`
639             value=no
640             type=bool
641             set_option
642             ;;
643         --[a-z]*)
644             option=`expr X"$arg" : 'X--\(.*\)'`
645             value=yes
646             type=bool
647             set_option
648             ;;
649         -*)
650             echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
651             exit 1
652             ;;
653         *)
654             if test X"$command" = X; then
655                 command=$arg
656             else
657                 echo >&2 "$0: exactly one non-option argument required (use --help for help)"
658                 exit 1
659             fi
660             ;;
661     esac
662 done
663 case $command in
664     start)
665         start_ovsdb
666         start_forwarding
667         ;;
668     stop)
669         stop_forwarding
670         stop_ovsdb
671         ;;
672     restart)
673         restart
674         ;;
675     status)
676         rc=0
677         for daemon in `daemons`; do
678             daemon_status $daemon || rc=$?
679         done
680         exit $rc
681         ;;
682     version)
683         for daemon in `daemons`; do
684             $daemon --version
685         done
686         ;;
687     force-reload-kmod)
688             force_reload_kmod
689         ;;
690     load-kmod)
691         insert_mod_if_required
692         ;;
693     enable-protocol)
694         enable_protocol
695         ;;
696     help)
697         usage
698         ;;
699     '')
700         echo >&2 "$0: missing command name (use --help for help)"
701         exit 1
702         ;;
703     *)
704         echo >&2 "$0: unknown command \"$command\" (use --help for help)"
705         exit 1
706         ;;
707 esac