]> git.ipfire.org Git - thirdparty/util-linux.git/blob - tools/checkusage.sh
tools: checkusage can dump all command output
[thirdparty/util-linux.git] / tools / checkusage.sh
1 #!/bin/bash
2
3 ## This script is potentially dangerous! Don't run it on
4 ## arbitrary commands.
5
6 export LC_ALL=C
7
8 if [ "$#" -lt 1 ]; then
9 echo "usage: $0 program..." >&2
10 echo " or try 'make checkusage' to check all built programs" >&2
11 exit 1
12 fi
13
14 builddir="."
15 cmds=$(echo $@ | tr ' ' '\n' | sort)
16
17 # set env to dump all output to files
18 test -z "$CU_DUMP" || rm -f /tmp/checkusage--{help,version,unknownopt}
19
20 ## Set alternative options for --help, --version
21 ## or --unknownopt. "x" means "not implemented".
22 ##
23 ## Examples:
24 ## alt_whereis__help="-h" # in past whereis(1) had no longopt for --help
25 ## alt_more__help="x" # more(1) had neither --help nor -h
26
27 alt_fsck__unknownopt="x" # fsck passes unknown opts to fsck.ext4, etc.
28 alt_mkfs__unknownopt="x" # dito
29 alt_kill__unknownopt="inval pids" # trick, kill does not use errtryhelp()
30 if [ $(id -ru) -eq 0 ]; then
31 alt_sulogin__unknownopt="x" # would hang at pwd prompt
32 fi
33
34 function exec_option {
35 local cmdb=$1
36 local cmd=$2
37 opt=$3
38 local tofile="/tmp/checkusage$opt"
39
40 local alt="alt_${cmdb}${opt}"
41 alt=${alt//-/_}
42 alt=${alt//./_}
43 alt=$(eval printf -- \"\$${alt}\")
44 if test -n "$alt"; then
45 if test "$alt" = "x"; then
46 return 1
47 fi
48 opt=$alt
49 fi
50
51 test -z "$CU_DUMP" || {
52 echo "##########################################################"
53 echo "#### $cmdb"
54 $cmd $opt
55 } >> "$tofile" 2>&1
56
57 out=$("$cmd" $opt 2>/dev/null)
58 err=$("$cmd" $opt 2>&1 >/dev/null)
59 ret=$?
60
61 # hardcoded ... nologin should always return false
62 if test "$cmdb" = "nologin" &&
63 test "$opt" = "--help" -o "$opt" = "--version"; then
64 if test "$ret" = "0"; then
65 echo "$cmdb, $opt, should return false"
66 fi
67 ret=0
68 fi
69
70 return 0
71 }
72
73
74 function check_help {
75 local cb=$1
76 local c=$2
77
78 if ! exec_option "$cb" "$c" --help; then
79 return 1
80 fi
81
82 if test $ret != 0; then
83 echo "$cb: $opt, returns error"
84 else
85 if test -z "$out"; then
86 echo "$cb: $opt, no stdout"
87 fi
88 if test -n "$err"; then
89 echo "$cb: $opt, non-empty stderr"
90 fi
91 fi
92 return 0
93 }
94
95 function check_version {
96 local cb=$1
97 local c=$2
98
99 if ! exec_option "$cb" "$c" --version; then
100 return 1
101 fi
102
103 if test $ret != 0; then
104 echo "$cb: $opt, returns error"
105 else
106 if test -z "$out"; then
107 echo "$cb: $opt, no stdout"
108 fi
109 if test -n "$err"; then
110 echo "$cb: $opt, non-empty stderr"
111 fi
112 fi
113 }
114
115 function check_unknownopt {
116 local cb=$1
117 local c=$2
118 local nohelp=$3
119
120 if ! exec_option "$cb" "$c" --unknownopt; then
121 return 1
122 fi
123
124 if test $ret = 0; then
125 echo "$cb: $opt, returns no error"
126 fi
127 if test -n "$out"; then
128 echo "$cb: $opt, non-empty stdout"
129 fi
130 if test -z "$err"; then
131 echo "$cb: $opt, no stderr"
132 elif test -z "$nohelp" -o "$nohelp" != "yes"; then
133 out_len=$(echo "$out" | wc -l)
134 err_len=$(echo "$err" | wc -l)
135 if test "$err_len" -gt 2; then
136 echo "$cb: $opt, stderr too long: $err_len"
137 elif test "$err_len" -lt 2; then
138 echo "$cb: $opt, stderr too short: $err_len"
139 fi
140 fi
141 }
142
143 for cb in $cmds; do
144 c="$builddir/$cb"
145 if ! type "$c" &>/dev/null; then
146 echo "$cb: does not exist"
147 continue
148 fi
149
150 nohelp="no"
151 if ! check_help "$cb" "$c"; then
152 nohelp="yes"
153 fi
154 check_version "$cb" "$c"
155 check_unknownopt "$cb" "$c" "$nohelp"
156 done
157