Get rid of generated files which are empty
[grml-hwinfo.git] / grml-hwinfo
1 #!/bin/bash
2 # Filename:      grml-hwinfo
3 # Purpose:       get hardware information
4 # Authors:       grml-team (grml.org), (c) Michael Prokop <mika@grml.org>
5 # Bug-Reports:   see http://grml.org/bugs/
6 # License:       This file is licensed under the GPL v2.
7 ################################################################################
8 # Notice: Some ideas have been taken from
9 # http://club.black.co.at/david/hwdb/infodump
10 # by David Schmitt <david@schmitt.edv-bus.at>
11 ################################################################################
12
13 # variables
14 UNAME="$(uname -r)"
15 PN="$(basename $0)"
16 [ -n "$WORKING_DIR" -a -d "$WORKING_DIR" ] || WORKING_DIR=$(pwd)
17 VERSION='***UNRELEASED***'
18
19 # data collection should not be affected by user locale
20 export LANG=C
21 export LC_ALL=C
22
23 TIMESTAMP='+%F--%H-%M-%S-%Z'
24 DATE="$(date $TIMESTAMP)"
25
26 echo "$PN ${VERSION} - collect hardware information"
27
28 GENERATE_FILE='1'
29 GENERATE_DIRECTORY=''
30
31 while getopts "hdf" args; do
32   case "$args" in
33   h) echo "
34 This tool collects information of the hardware this tool is being executed
35 on.  It can be executed as normal user to collect some basic information or
36 with root permissions to collect as much information as possible.  By
37 default, a file named grml-hwinfo-TIMESTAMP.tar.bz2 storing all collected
38 information will be created in the current working directory. Alternatively,
39 you can have it create a directory with all information.
40
41 Options:
42
43   -h    Display this help message
44   -f    Create grml-hwinfo-TIMESTAMP.tar.bz2
45   -d    Create grml-hwinfo-TIMESTAMP as a directory
46   -df   Create both, the directory and the file
47 "
48
49   exit 0;;
50
51   d)
52   GENERATE_FILE=''
53   GENERATE_DIRECTORY='1'
54   ;;
55
56   f) # generating file; default behaviour
57   GENERATE_FILE='1'
58   ;;
59
60   esac
61   done
62
63 # Generate output/temporary directory name & path, and output file path
64 OUTFILE=""
65 OUTDIRNAME="grml-hwinfo-${DATE}"
66 OUTDIR="${WORKING_DIR}/${OUTDIRNAME}"
67 mkdir "${OUTDIR}" || { echo 'Directory "'${OUTDIR}'" already exists, aborting.'>&2 ; exit 1; }
68
69 if [ -n "$GENERATE_FILE" ] ; then
70    OUTFILE_="${OUTDIR}.tar.bz2"
71    [ -e "${OUTFILE_}" ] && { echo 'File "'${OUTFILE_}'" already exists, aborting.'>&2 ; rm -r "${OUTDIR}"; exit 1; }
72    OUTFILE=${OUTFILE_}
73    touch "${OUTFILE}"
74 fi
75
76 if [ "$(id -u)" != "0" ] ; then
77    NOTROOT=1
78    echo "W: Running without root permissions. Not all data will be collected."
79 fi
80
81 # check whether a binary is available and executable
82 exectest() {
83 if [ -z "$1" ] ; then
84    echo 'Usage: exectest <binary>'>&2
85    return 1
86 else
87    if test -e "$(which $1)" ; then
88      return 0
89    else
90      grep -q "^$1"'$' missing_tools 2>/dev/null || echo "$1" >> missing_tools
91      return 1
92    fi
93 fi
94 }
95
96 # echo a list of all disks and their size
97 # taken from http://cvs.debian.org/fai/lib/disk-info
98 diskandsize() {
99     local isdisk major minor blocks device suffix
100     while read major minor blocks device suffix; do
101         isdisk=1
102         # skip ide cdrom
103         [ -f /proc/ide/$device/media ] && grep -q cdrom /proc/ide/$device/media && isdisk=0
104         [ "$isdisk" -eq 1 ] && echo "$device $blocks"
105     done
106 }
107
108 list_disks() {
109 # print only every second entry; used by disk_info
110 i=0
111 for ent in $@; do
112     if [ "$i" -eq 0 ]; then
113         echo $ent
114         i=1
115     else
116         i=0
117     fi
118 done
119 }
120
121 disk_info() {
122     # the variable holds a space separated list of devices and their block size
123     device_size=`grep -E ' cciss/c.d.$| ida/c.d.$| rd/c.d.$| hd.$| sd.$|/disc$' /proc/partitions | diskandsize`
124     # a list of all local disks, without size
125     disklist=`list_disks $device_size`
126 }
127
128
129 cd "${OUTDIR}" || exit 1
130 (
131   [ -n "$GENERATE_FILE" ]      && echo "Output file:      $OUTFILE"
132   [ -n "$GENERATE_DIRECTORY" ] && echo "Output directory: $OUTDIR"
133   echo
134   echo "This might take a few seconds/minutes. Please be patient..."
135
136 # some sysinfo
137   date > date
138   if [ -r /etc/grml_version ] ; then
139      cat /etc/grml_version > grml_version
140   fi
141   if [ -r /etc/debian_version ] ; then
142      cat /etc/debian_version > debian_version
143   fi
144   uname -a > uname
145
146 # disks / devices
147   [ -f /proc/scsi/scsi ] && cat /proc/scsi/scsi > scsi
148   (lspci; lspci -n) | sort > lspci
149   [ -r /proc/bus/pnp ] && lspnp > lspnp
150   [ -r /proc/bus/usb ] && lsusb > lsusb
151   cat /proc/partitions > partitions
152   find /proc/ide/ -name geometry -exec grep . {} \; > proc_ide 2>/dev/null
153   df -h > df 2>/dev/null
154   for i in free lsmod mount lsdev ; do
155       exectest $i  && $i > $i
156   done
157   swapon -s > swapon 2>swapon.error
158
159 # proc stuff
160   for i in cpuinfo interrupts cmdline devices dma fb iomem ioports \
161     mdstat meminfo modules mtrr pci version ; do
162     [ -r /proc/$i ] && cat /proc/$i > proc_$i
163   done
164   exectest sysdump  && sysdump > sysdump 2>sysdump.error
165 # for sysnet in `find /proc/sys/net/*/ -type f | grep -v flush`; do cat $sysnet >> sysnet ; done
166
167 # log
168   dmesg > dmesg.cur
169
170 # hwinfo
171   exectest discover && discover -v --type-summary --enable-bus all > discover 2> discover.2
172   exectest hwinfo   && hwinfo log=hwinfo
173   exectest numactl  && numactl --hardware > numactl
174   exectest x86info  && x86info > x86info 2>x86info.2
175
176 # net stuff
177   exectest ifconfig  && ifconfig -v -a  > ifconfig
178   exectest ip        && ip route show   > ip_route
179   exectest ip        && ip link show    > ip_link
180   exectest route     && route -n        > route
181
182 # software
183   if exectest dpkg ; then
184      dpkg --get-selections   > dpkg_get_selections
185      COLUMNS=300 dpkg --list > dpkg_list
186   fi
187
188 # power management
189   exectest laptop-detect  && laptop-detect >/dev/null 2>/dev/null && echo "0" > laptop_detected
190   exectest acpi_available && acpi_available && cat /proc/acpi/info > acpi_info
191   exectest acpi && acpi > acpi 2> acpi.error && acpi -v > acpi.version
192   [ -r /proc/apm/ ] && apm > apm
193
194 # kernel stuff
195   if [ -r /proc/config.gz ] ; then
196      zcat /proc/config.gz > kernelconfig
197   else
198      [ -r /boot/config-$UNAME ] && cat /boot/config-$UNAME > kernelconfig
199   fi
200
201   exectest dpkg && COLUMNS=1000 dpkg -l linux-image-$UNAME \
202            | grep linux-image-$UNAME | tr -s ' ' > running_kernel 2>running_kernel.error
203   dpkg -S /boot/vmlinuz-$(uname -r) >> running_kernel 2>>running_kernel.error
204
205 # X stuff
206   if [ -n "${DISPLAY}" ] ; then
207      exectest xviddetect  && xviddetect         > xviddetect
208      exectest xvidtune    && xvidtune -show     > xdivtune
209      exectest xrandr      && xrandr             > xrandr
210      exectest xdpyinfo    && xdpyinfo           > xdpyinfo
211      X -version > x_version 2>&1
212   fi
213
214   for i in Xorg.0.log Xorg.7.log Xorg.8.log XFree86.0.log XFree86.7.log XFree86.8.log dmesg ; do
215       cp /var/log/$i log_$i 2>/dev/null
216   done
217
218   cp /etc/X11/xorg.conf    xorg.conf    2>/dev/null
219   cp /etc/modules          modules      2>/dev/null
220   cp /etc/X11/XF86Config-4 XF86Config-4 2>/dev/null
221
222 # not available:
223 # sysinfo -class device -level all
224
225 # as root:
226 if [ -n "$NOTROOT" ] ; then
227    echo "not running as root" > root
228 else
229    echo "running as root" > root
230    disk_info
231    exectest sfdisk     && sfdisk -d > sfdisk 2>sfdisk.error
232    exectest dmidecode  && dmidecode > dmidecode
233
234    exectest dconf && dconf -o dconf
235
236    if [ -x /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl ] ; then
237       /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl > decode-dimms 2>decode-dimms.error
238    fi
239
240    exectest mdadm && mdadm --detail /dev/md[0-9]* >> mdadm 2>mdadm.error
241
242    # LVM
243    exectest pvs && pvs > pvs 2>pvs.error
244    exectest vgs && vgs > vgs 2>vgs.error
245    exectest lvs && lvs > lvs 2>lvs.error
246    exectest lvdisplay && lvdisplay > lvdisplay 2>lvdisplay.error
247
248    exectest dmsetup && dmsetup ls > dmsetup_ls 2>dmsetup_ls.error
249
250    for disk in $disklist; do
251       exectest smartctl  && echo "smartctl -a /dev/$disk :\n" >> smartctl && smartctl -a /dev/$disk       >> smartctl             && echo "\n\n" >> smartctl
252       exectest hdparm    && echo "hdparm -iv  /dev/$disk :\n" >> hdparm   && hdparm -iv  /dev/$disk       >> hdparm               && echo "\n\n" >> hdparm
253       exectest fdisk     && echo "fdisk -lu   /dev/$disk :\n" >> fdisk    && fdisk -lu   /dev/$disk       >> fdisk 2>>fdisk.error && echo "\n\n" >> fdisk
254       exectest parted    && echo "parted -s   /dev/$disk :\n" >> parted   && parted -s   /dev/$disk print >> parted               && echo "\n\n" >> parted
255       file -s /dev/$disk?* | grep -v ": empty" >> file_disk
256    done
257 fi
258 )
259
260 # get rid of empty files
261 for file in *; do
262   test -s $file || rm $file
263 done
264
265 echo
266
267 cd "${WORKING_DIR}"
268
269 # create tarball
270 if [ -n "$GENERATE_FILE" ] ; then
271   tar jcf "${OUTFILE}" "${OUTDIRNAME}"
272   [ -r "$OUTFILE" ] && echo "$OUTFILE ("$(ls -ahl "$OUTFILE" | awk '{print $5}')") has been generated."
273 fi
274
275 # remove (temporary) output directory if needed, else keep it, as it doubles
276 # as the real output directory.
277 if [ -z "$GENERATE_DIRECTORY" ] ; then
278   rm -r "${OUTDIR}"
279 else
280   [ -r "${OUTDIR}" ] && echo "${OUTDIR} has been generated."
281 fi
282
283 exit 0
284
285 ## END OF FILE##################################################################