58
93
# End tmpdir package
59
94
# ###########################################################################
96
# ###########################################################################
97
# parse_options package
98
# This package is a copy without comments from the original. The original
99
# with comments and its test file can be found in the Bazaar repository at,
100
# lib/bash/parse_options.sh
101
# t/lib/bash/parse_options.sh
102
# See https://launchpad.net/percona-toolkit for more information.
103
# ###########################################################################
111
ARGV="" # Non-option args (probably input files)
112
EXT_ARGV="" # Everything after -- (args for an external command)
113
HAVE_EXT_ARGV="" # Got --, everything else is put into EXT_ARGV
114
OPT_ERRS=0 # How many command line option errors
115
OPT_VERSION="" # If --version was specified
116
OPT_HELP="" # If --help was specified
117
PO_DIR="" # Directory with program option spec files
122
local usage="$(grep '^Usage: ' "$file")"
125
echo "For more information, 'man $TOOL' or 'perldoc $file'."
131
if [ "$OPT_VERSION" ]; then
132
local version=$(grep '^pt-[^ ]\+ [0-9]' "$file")
137
if [ "$OPT_HELP" ]; then
140
echo "Command line options:"
144
use warnings FATAL => qw(all);
145
my $lcol = 20; # Allow this much space for option names.
146
my $rcol = 80 - $lcol; # The terminal is assumed to be 80 chars wide.
151
if ( $line =~ s/^long:/ --/ ) {
154
elsif ( $line =~ s/^desc:// ) {
156
my @lines = grep { $_ }
157
$line =~ m/(.{0,$rcol})(?:\s+|\Z)/g;
158
if ( length($name) >= $lcol ) {
159
print $name, "\n", (q{ } x $lcol);
162
printf "%-${lcol}s", $name;
164
print join("\n" . (q{ } x $lcol), @lines);
170
echo "Options and values after processing arguments:"
175
local varname="OPT_$(echo "$opt" | tr a-z- A-Z_)"
176
eval local varvalue=\$$varname
177
if ! grep -q "type:" "$PO_DIR/$opt" >/dev/null; then
178
if [ "$varvalue" -a "$varvalue" = "yes" ];
184
printf -- " --%-30s %s" "$opt" "${varvalue:-(No value)}"
191
if [ $OPT_ERRS -gt 0 ]; then
202
OPT_ERRS=$(($OPT_ERRS + 1))
216
PO_DIR="$PT_TMPDIR/po"
218
if [ ! -d "$PO_DIR" ]; then
220
if [ $? -ne 0 ]; then
221
echo "Cannot mkdir $PO_DIR" >&2
227
if [ $? -ne 0 ]; then
228
echo "Cannot rm -rf $PO_DIR/*" >&2
232
_parse_pod "$file" # Parse POD into program option (po) spec files
233
_eval_po # Eval po into existence with default values
235
if [ $# -ge 2 ] && [ "$1" = "--config" ]; then
237
local user_config_files="$1"
240
for user_config_file in $user_config_files; do
241
_parse_config_files "$user_config_file"
244
_parse_config_files "/etc/percona-toolkit/percona-toolkit.conf" "/etc/percona-toolkit/$TOOL.conf" "$HOME/.percona-toolkit.conf" "$HOME/.$TOOL.conf"
247
_parse_command_line "${@:-""}"
253
cat "$file" | PO_DIR="$PO_DIR" perl -ne '
255
next unless $_ =~ m/^=head1 OPTIONS/;
256
while ( defined(my $para = <>) ) {
257
last if $para =~ m/^=head1/;
259
if ( $para =~ m/^=item --(\S+)/ ) {
261
my $file = "$ENV{PO_DIR}/$opt";
262
open my $opt_fh, ">", $file or die "Cannot open $file: $!";
263
print $opt_fh "long:$opt\n";
266
if ( $para =~ m/^[a-z ]+:/ ) {
269
my ($attrib, $val) = split(/: /, $_);
270
print $opt_fh "$attrib:$val\n";
271
} split(/; /, $para);
275
my ($desc) = $para =~ m/^([^?.]+)/;
276
print $opt_fh "desc:$desc.\n";
286
for opt_spec in "$PO_DIR"/*; do
291
while read key val; do
294
opt=$(echo $val | sed 's/-/_/g' | tr '[:lower:]' '[:upper:]')
302
[ "$val" = "size" ] && size=1
307
if [ "$val" = "yes" ]; then
312
echo "Invalid attribute in $opt_spec: $line" >&2
317
if [ -z "$opt" ]; then
318
echo "No long attribute in option spec $opt_spec" >&2
322
if [ $neg -eq 1 ]; then
323
if [ -z "$default_val" ] || [ "$default_val" != "yes" ]; then
324
echo "Option $opt_spec is negatable but not default: yes" >&2
329
if [ $size -eq 1 -a -n "$default_val" ]; then
330
default_val=$(size_to_bytes $default_val)
333
eval "OPT_${opt}"="$default_val"
337
_parse_config_files() {
339
for config_file in "${@:-""}"; do
340
test -f "$config_file" || continue
342
while read config_opt; do
344
echo "$config_opt" | grep '^[ ]*[^#]' >/dev/null 2>&1 || continue
346
config_opt="$(echo "$config_opt" | sed -e 's/^ *//g' -e 's/ *$//g' -e 's/[ ]*=[ ]*/=/' -e 's/[ ]*#.*$//')"
348
[ "$config_opt" = "" ] && continue
350
if ! [ "$HAVE_EXT_ARGV" ]; then
351
config_opt="--$config_opt"
354
_parse_command_line "$config_opt"
356
done < "$config_file"
358
HAVE_EXT_ARGV="" # reset for each file
363
_parse_command_line() {
366
local next_opt_is_val=""
368
local opt_is_negated=""
370
local required_arg=""
373
for opt in "${@:-""}"; do
374
if [ "$opt" = "--" -o "$opt" = "----" ]; then
378
if [ "$HAVE_EXT_ARGV" ]; then
379
if [ "$EXT_ARGV" ]; then
380
EXT_ARGV="$EXT_ARGV $opt"
387
if [ "$next_opt_is_val" ]; then
389
if [ $# -eq 0 ] || [ $(expr "$opt" : "\-") -eq 1 ]; then
390
option_error "$real_opt requires a $required_arg argument"
396
if [ $(expr "$opt" : "\-") -eq 0 ]; then
397
if [ -z "$ARGV" ]; then
407
if $(echo $opt | grep '^--no[^-]' >/dev/null); then
408
local base_opt=$(echo $opt | sed 's/^--no//')
409
if [ -f "$PT_TMPDIR/po/$base_opt" ]; then
414
opt=$(echo $opt | sed 's/^-*//')
417
if $(echo $opt | grep '^--no-' >/dev/null); then
419
opt=$(echo $opt | sed 's/^--no-//')
422
opt=$(echo $opt | sed 's/^-*//')
426
if $(echo $opt | grep '^[a-z-][a-z-]*=' >/dev/null 2>&1); then
427
val="$(echo $opt | awk -F= '{print $2}')"
428
opt="$(echo $opt | awk -F= '{print $1}')"
431
if [ -f "$PT_TMPDIR/po/$opt" ]; then
432
spec="$PT_TMPDIR/po/$opt"
434
spec=$(grep "^short form:-$opt\$" "$PT_TMPDIR"/po/* | cut -d ':' -f 1)
435
if [ -z "$spec" ]; then
436
option_error "Unknown option: $real_opt"
441
required_arg=$(cat "$spec" | awk -F: '/^type:/{print $2}')
442
if [ "$required_arg" ]; then
450
option_error "Option $real_opt does not take a value"
453
if [ "$opt_is_negated" ]; then
462
if [ "$opt_is_ok" ]; then
463
opt=$(cat "$spec" | grep '^long:' | cut -d':' -f2 | sed 's/-/_/g' | tr '[:lower:]' '[:upper:]')
465
if grep "^type:size" "$spec" >/dev/null; then
466
val=$(size_to_bytes $val)
469
eval "OPT_$opt"="'$val'"
485
echo $size | perl -ne '%f=(B=>1, K=>1_024, M=>1_048_576, G=>1_073_741_824, T=>1_099_511_627_776); m/^(\d+)([kMGT])?/i; print $1 * $f{uc($2 || "B")};'
488
# ###########################################################################
489
# End parse_options package
490
# ###########################################################################
492
# ###########################################################################
494
# This package is a copy without comments from the original. The original
495
# with comments and its test file can be found in the Bazaar repository at,
496
# lib/bash/alt_cmds.sh
497
# t/lib/bash/alt_cmds.sh
498
# See https://launchpad.net/percona-toolkit for more information.
499
# ###########################################################################
506
awk "BEGIN { for(i=1; i<=$i; i++) print i; }"
511
if ! pidof "$cmd" 2>/dev/null; then
512
ps -eo pid,ucomm | awk -v comm="$cmd" '$2 == comm { print $1 }'
518
if ! lsof -p $pid 2>/dev/null; then
519
/bin/ls -l /proc/$pid/fd 2>/dev/null
526
if [ -x /usr/bin/which ]; then
527
/usr/bin/which "$1" 2>/dev/null | awk '{print $1}'
528
elif which which 1>/dev/null 2>&1; then
529
which "$1" 2>/dev/null | awk '{print $1}'
535
# ###########################################################################
536
# End alt_cmds package
537
# ###########################################################################
541
# Parse command line options.
543
parse_options "$0" "${@:-""}"
545
if [ -z "$OPT_HELP" -a -z "$OPT_VERSION" ]; then
546
if [ -z "$EXT_ARGV" ]; then
547
option_error "No COMMAND was given."
554
if [ $po_status -ne 0 ]; then
555
[ $OPT_ERRS -gt 0 ] && exit 1
63
559
FILE="$PT_TMPDIR/mext_temp_file";
67
# Command-line parsing.
68
args=`getopt -u -n mext r "$@"`;
69
if [ "$?" = "1" ]; then
84
562
# Split the output on empty lines and put each into a different file; eliminate
85
563
# lines that don't have "real" content.
86
$@ | grep -v '+' | grep -v Variable_name | sed 's/|//g' \
564
$EXT_ARGV | grep -v '+' | grep -v Variable_name | sed 's/|//g' \
87
565
| while read line; do
88
566
if [ "$line" = "" ]; then
90
568
echo "" > "$FILE$NUM"
92
570
echo "$line" >> "$FILE$NUM"
95
# Count how many files there are and prepare to format the output
576
# Count how many files there are and prepare to format the output, but...
98
577
NUM=`ls "$FILE"* | wc -l`;
99
# The last file will be empty...
579
# ... iterate through files 1..(N-2) because the last file is empty and
580
# we join N to N+1 so also don't read the last real file.
102
583
# Join each file with the next file, joining on the first field. Build a printf
103
584
# spec and awk spec at the same time.
104
for i in `seq 0 $NUM`; do
105
NEXTFILE=`expr $i + 1`;
585
for i in `_seq $NUM`; do
107
588
# Sort each file and eliminate empty lines, so 'join' doesn't complain.
108
589
sort "$FILE$i" | grep . > "$FILE$i.tmp"