lsb_release 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. #!/bin/sh
  2. # About: This shell script is the lsb_release implementation,
  3. # Version: see SCRIPTVERSION (in the Declarations section)
  4. # Licence: GPL (latest version), Free Software Group, Inc
  5. # Author: Dominique MASSONIE <mdomi@users.sourceforge.net>
  6. # Date: September 27th, 2000
  7. #
  8. # * Changes in 1.4
  9. # - "awk" not needed anymore (Loic Lefort)
  10. # - fixed bug #121879 reported by Chris D. Faulhaber,
  11. # some shells doesn't support local variables
  12. # - fixed a bug when single parameter sets many args including -s
  13. # - function DisplayProgramVersion (undocumented) now exits script like Usage
  14. # - cosmetic changes in comments/outputs
  15. #
  16. # * Changes in 1.3
  17. # - No changes in script, only in build infrastructure
  18. #
  19. # * Changes in 1.2
  20. # - Fixed more bash'isms
  21. # - LSB_VERSION is no longer required in /etc/lsb-release file
  22. #
  23. # * Changes in 1.1
  24. # - removed some bash-ism and typos (me)
  25. # Notice: script remains broken with ash because of awk issues
  26. # - changed licence to FSG - "Free Software Group, Inc" (me)
  27. # - fixed problem with --short single arg call (me)
  28. # - changed Debian specifics, codename anticipates release num (me)
  29. #
  30. # Description:
  31. # Collect informations from sourceable /etc/lsb-release file (present on
  32. # LSB-compliant systems) : LSB_VERSION, DISTRIB_ID, DISTRIB_RELEASE,
  33. # DISTRIB_CODENAME, DISTRIB_DESCRIPTION (all optional).
  34. # Then (if needed) find and parse the /etc/[distro]-release file.
  35. ###############################################################################
  36. # DECLARATIONS
  37. ###############################################################################
  38. # This script version
  39. SCRIPTVERSION="1.4"
  40. # Defines the data files
  41. INFO_ROOT="/etc" # directory of config files
  42. INFO_LSB_FILE="lsb-release" # where to get LSB version
  43. INFO_DISTRIB_SUFFIX="release" # <distrib>-<suffix>
  44. ALTERNATE_DISTRIB_FILE="/etc/debian_version" # for Debian [based distrib]
  45. ALTERNATE_DISTRIB_NAME="Debian" # "
  46. CHECKFIRST="/etc/redhat-release" # check it before file search
  47. # Defines our exit codes
  48. EXIT_STATUS="0" # default = Ok :)
  49. ERROR_UNKNOWN="10" # unknown error
  50. ERROR_USER="1" # program misuse
  51. ERROR_PROGRAM="2" # internal error
  52. ERROR_NOANSWER="3" # all required info not available
  53. # typically non LSB compliant distro!
  54. # Defines our messages
  55. MSG_LSBVER="LSB Version:\t"
  56. MSG_DISTID="Distributor ID:\t"
  57. MSG_DISTDESC="Description:\t"
  58. MSG_DISTREL="Release:\t"
  59. MSG_DISTCODE="Codename:\t"
  60. MSG_NA="n/a"
  61. MSG_NONE="(none)"
  62. MSG_RESULT="" # contains the result in case short output selected
  63. # Description string delimiter
  64. DESCSTR_DELI="release"
  65. ###############################################################################
  66. # FUNCTIONS
  67. ###############################################################################
  68. # Display Program Version for internal use (needed by help2man)
  69. DisplayProgramVersion() {
  70. echo "FSG `basename $0` v$SCRIPTVERSION"
  71. echo
  72. echo "Copyright (C) 2000 Free Software Group, Inc."
  73. echo "This is free software; see the source for copying conditions. There\
  74. is NO"
  75. echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR\
  76. PURPOSE."
  77. echo
  78. echo "Written by Dominique MASSONIE."
  79. exit $EXIT_STATUS
  80. }
  81. # defines the Usage for lsb_release
  82. Usage() {
  83. echo "FSG `basename $0` v$SCRIPTVERSION prints certain LSB (Linux\
  84. Standard Base) and"
  85. echo "Distribution information."
  86. echo
  87. echo "Usage: `basename $0` [OPTION]..."
  88. echo "With no OPTION specified it is the same as -v."
  89. echo
  90. echo "Options:"
  91. echo " -v, --version"
  92. echo " Display the version of the LSB specification against which the distribution is compliant."
  93. echo " -i, --id"
  94. echo " Display the string id of the distributor."
  95. echo " -d, --description"
  96. echo " Display the single line text description of the distribution."
  97. echo " -r, --release"
  98. echo " Display the release number of the distribution."
  99. echo " -c, --codename"
  100. echo " Display the codename according to the distribution release."
  101. echo " -a, --all"
  102. echo " Display all of the above information."
  103. echo " -s, --short"
  104. echo " Display all of the above information in short output format."
  105. echo " -h, --help"
  106. echo " Display this message."
  107. exit $EXIT_STATUS
  108. }
  109. # Handles the enhanced args (i.e. --something)
  110. EnhancedGetopt() {
  111. getopt -T >/dev/null 2>&1 # is getopt the enhanced one ?
  112. if [ $? = 4 ]
  113. then # Yes, advanced args ALLOWED
  114. OPT=$(getopt -o acdhirsvp \
  115. --long all,codename,description,help,id,release,short,version,program_version \
  116. -n 'lsb_release' \
  117. -- "$@")
  118. else # No, advanced args NOT allowed
  119. # convert (if needed) the enhanced options into basic ones
  120. MYARGS=$(echo "$@" | sed -e "/--/s/-\(-[[:alnum:]]\)[[:alnum:]]*/\1/g")
  121. OPT=$(getopt -o acdhirsvp \
  122. -n 'lsb_release' \
  123. -- "$MYARGS")
  124. fi
  125. if [ $? != 0 ]
  126. then
  127. exit $ERROR_PROGRAM
  128. fi
  129. NB_ARG="" # enabled if many args set in one parameter (i.e. -dris)
  130. eval set -- "$OPT"
  131. while true ; do
  132. case "$1" in
  133. -a|--all) ARG_A="y"; NB_ARG="y"; shift;;
  134. -c|--codename) ARG_C="y"; NB_ARG="y"; shift;;
  135. -d|--description) ARG_D="y"; NB_ARG="y"; shift;;
  136. -i|--id) ARG_I="y"; NB_ARG="y"; shift;;
  137. -r|--release) ARG_R="y"; NB_ARG="y"; shift;;
  138. -s|--short) ARG_S="y"; shift;;
  139. -v|--version) ARG_V="y"; NB_ARG="y"; shift;;
  140. -p|--program_version) DisplayProgramVersion;;
  141. -h|--help) Usage;;
  142. --) shift; break;;
  143. *) EXIT_STATUS=$ERROR_USER
  144. Usage;;
  145. esac
  146. done
  147. }
  148. # Get/Init LSB infos (maybe Distrib infos too)
  149. GetLSBInfo() {
  150. if [ -f "$INFO_ROOT/$INFO_LSB_FILE" ]
  151. then
  152. # should init at least LSB_VERSION
  153. . "$INFO_ROOT/$INFO_LSB_FILE"
  154. fi
  155. [ -z "$LSB_VERSION" ] && LSB_VERSION=$MSG_NA
  156. }
  157. # Get the whole distrib information string (from ARG $1 file)
  158. InitDistribInfo() {
  159. ## Notice: Debian has a debian_version file
  160. ## (at least) Mandrake has two files, a mandrake and a redhat one
  161. FILENAME=$1 # CHECKFIRST or finds' result in GetDistribInfo() or ""
  162. if [ -z "$FILENAME" ]
  163. then
  164. if [ -f "$ALTERNATE_DISTRIB_FILE" ]
  165. then # For Debian only
  166. [ -z "$DISTRIB_ID" ] && DISTRIB_ID="$ALTERNATE_DISTRIB_NAME"
  167. [ -z "$DISTRIB_RELEASE" ] \
  168. && DISTRIB_RELEASE=$(cat $ALTERNATE_DISTRIB_FILE)
  169. [ -z "$DISTRIB_CODENAME" ] && [ "$DISTRIB_RELEASE" = "2.1" ] \
  170. && DISTRIB_CODENAME="Slink"
  171. [ -z "$DISTRIB_CODENAME" ] && [ "$DISTRIB_RELEASE" = "2.2" ] \
  172. && DISTRIB_CODENAME="Potato"
  173. # [ -z "$DISTRIB_CODENAME" ] && [ "$DISTRIB_RELEASE" = "2.3" ] \
  174. # && DISTRIB_CODENAME="Woody"
  175. [ -z "$DISTRIB_CODENAME" ] && DISTRIB_CODENAME=$DISTRIB_RELEASE
  176. # build the DISTRIB_DESCRIPTION string (never need to be parsed)
  177. [ -z "$DISTRIB_DESCRIPTION" ] \
  178. && DISTRIB_DESCRIPTION="$DISTRIB_ID $DESCSTR_DELI $DISTRIB_REL\
  179. EASE ($DISTRIB_CODENAME)"
  180. else # Only for nothing known compliant distrib :(
  181. [ -z "$DISTRIB_ID" ] && DISTRIB_ID=$MSG_NA
  182. [ -z "$DISTRIB_RELEASE" ] && DISTRIB_RELEASE=$MSG_NA
  183. [ -z "$DISTRIB_CODENAME" ] && DISTRIB_CODENAME=$MSG_NA
  184. [ -z "$DISTRIB_DESCRIPTION" ] && DISTRIB_DESCRIPTION=$MSG_NONE
  185. EXIT_STATUS=$ERROR_NOANSWER
  186. fi
  187. else
  188. NO="" # is Description string syntax correct ?
  189. if [ -z "$DISTRIB_DESCRIPTION" ] \
  190. || [ -n "$(echo $DISTRIB_DESCRIPTION | \
  191. sed -e "s/.*$DESCSTR_DELI.*//")" ]
  192. then
  193. TMP_DISTRIB_DESC=$(head -1 $FILENAME 2>/dev/null)
  194. [ -z "$DISTRIB_DESCRIPTION" ] \
  195. && DISTRIB_DESCRIPTION=$TMP_DISTRIB_DESC
  196. else
  197. TMP_DISTRIB_DESC=$DISTRIB_DESCRIPTION
  198. fi
  199. if [ -z "$TMP_DISTRIB_DESC" ] # head or lsb-release init
  200. then # file contains no data
  201. DISTRIB_DESCRIPTION=$MSG_NONE
  202. NO="y"
  203. else # Do simple check
  204. [ -n "$(echo $TMP_DISTRIB_DESC | \
  205. sed -e "s/.*$DESCSTR_DELI.*//")" ] \
  206. && NO="y"
  207. fi
  208. if [ -n "$NO" ]
  209. then # does not contain "release" delimiter
  210. [ -z "$DISTRIB_ID" ] && DISTRIB_ID=$MSG_NA
  211. [ -z "$DISTRIB_RELEASE" ] && DISTRIB_RELEASE=$MSG_NA
  212. [ -z "$DISTRIB_CODENAME" ] && DISTRIB_CODENAME=$MSG_NA
  213. fi
  214. fi
  215. }
  216. # Check missing and requested infos, then find the file and get infos
  217. GetDistribInfo() {
  218. NO="" # /etc/lsb-release data are enough to reply what is requested?
  219. [ -n "$ARG_D" ] && [ -z "$DISTRIB_DESCRIPTION" ] && NO="y"
  220. [ -z "$NO" ] && [ -n "$ARG_I" ] && [ -z "$DISTRIB_ID" ] && NO="y"
  221. [ -z "$NO" ] && [ -n "$ARG_R" ] && [ -z "$DISTRIB_RELEASE" ] && NO="y"
  222. [ -z "$NO" ] && [ -n "$ARG_C" ] && [ -z "$DISTRIB_CODENAME" ] && NO="y"
  223. if [ -n "$NO" ]
  224. then
  225. if [ ! -f "$CHECKFIRST" ]
  226. then
  227. CHECKFIRST=$(find $INFO_ROOT/ -maxdepth 1 \
  228. -name \*$INFO_DISTRIB_SUFFIX \
  229. -and ! -name $INFO_LSB_FILE \
  230. -and -type f \
  231. 2>/dev/null \
  232. | head -1 ) # keep one of the files found (if many)
  233. fi
  234. InitDistribInfo $CHECKFIRST
  235. fi
  236. }
  237. # Display version of LSB against which distribution is compliant
  238. DisplayVersion() {
  239. if [ -z "$ARG_S" ]
  240. then
  241. echo -e "$MSG_LSBVER$LSB_VERSION" # at least "n/a"
  242. else
  243. MSG_RESULT="$MSG_RESULT${MSG_RESULT:+ }$LSB_VERSION"
  244. fi
  245. }
  246. # Display string id of distributor ( i.e. a single word! )
  247. DisplayID() {
  248. if [ -z "$DISTRIB_ID" ]
  249. then
  250. ## Linux could be part of the distro name (i.e. Turbolinux) or a separate word
  251. ## set before, after...
  252. ## also expect a delimiter ( i.e. "release" )
  253. if [ -n "$(echo $TMP_DISTRIB_DESC | sed "s/.*$DESCSTR_DELI.*//")" ]
  254. then
  255. DISTRIB_ID=$MSG_NA
  256. else
  257. DISTRIB_ID=$(echo " $TMP_DISTRIB_DESC" \
  258. | sed -e "s/[[:blank:]][Ll][Ii][Nn][Uu][Xx][[:blank:]]/ /g" \
  259. -e "s/\(.*\)[[:blank:]]$DESCSTR_DELI.*/\1/" -e "s/[[:blank:]]//g")
  260. fi
  261. fi
  262. if [ -z "$ARG_S" ]
  263. then
  264. echo -e "$MSG_DISTID$DISTRIB_ID"
  265. else
  266. MSG_RESULT="$MSG_RESULT${MSG_RESULT:+ }$DISTRIB_ID"
  267. fi
  268. }
  269. # Diplay single line text description of distribution
  270. DisplayDescription() {
  271. if [ -z "$DISTRIB_DESCRIPTION" ]
  272. then
  273. # should not be empty since GetDistribInfo called on Initialization !
  274. EXIT_STATUS=$ERROR_PROGRAM
  275. fi
  276. if [ -z "$ARG_S" ]
  277. then
  278. echo -e "$MSG_DISTDESC$DISTRIB_DESCRIPTION"
  279. else
  280. MSG_RESULT="$MSG_RESULT${MSG_RESULT:+ }\"$DISTRIB_DESCRIPTION\""
  281. fi
  282. }
  283. # Display release number of distribution.
  284. DisplayRelease() {
  285. if [ -z "$DISTRIB_RELEASE" ]
  286. then # parse the "$DISTRIB_DESCRIPTION" string
  287. DISTRIB_RELEASE=$(echo "$TMP_DISTRIB_DESC" | \
  288. sed -e "s/.*$DESCSTR_DELI[[:blank:]]*\([[:digit:]][[:graph:]]*\).*/\1/" )
  289. [ "$DISTRIB_RELEASE" = "$TMP_DISTRIB_DESC" ] \
  290. || [ -z "$DISTRIB_RELEASE" ] \
  291. && DISTRIB_RELEASE=$MSG_NA
  292. fi
  293. if [ -z "$ARG_S" ]
  294. then
  295. echo -e "$MSG_DISTREL$DISTRIB_RELEASE"
  296. else
  297. MSG_RESULT="$MSG_RESULT${MSG_RESULT:+ }$DISTRIB_RELEASE"
  298. fi
  299. }
  300. # Display codename according to distribution version.
  301. DisplayCodename() {
  302. if [ -z "$DISTRIB_CODENAME" ]
  303. then # parse the "$DISTRIB_DESCRIPTION" string
  304. DISTRIB_CODENAME=$(echo "$TMP_DISTRIB_DESC" | \
  305. sed -e "s/.*$DESCSTR_DELI.*(\(.*\)).*/\1/")
  306. [ "$DISTRIB_CODENAME" = "$TMP_DISTRIB_DESC" ] \
  307. || [ -z "$DISTRIB_CODENAME" ] \
  308. && DISTRIB_CODENAME=$MSG_NA
  309. fi
  310. if [ -z "$ARG_S" ]
  311. then
  312. echo -e "$MSG_DISTCODE$(echo "$DISTRIB_CODENAME" | \
  313. tr -d "[:blank:]")" # Remove blanks
  314. else
  315. MSG_RESULT="$MSG_RESULT${MSG_RESULT:+ }$(echo "$DISTRIB_CODENAME" | \
  316. tr -d "[:blank:]")"
  317. fi
  318. }
  319. ###############################################################################
  320. # MAIN
  321. ###############################################################################
  322. # Check if any prog argument
  323. if [ -z "$1" ]
  324. then
  325. ARG_V="y" # default set to Display LSB Version (not Usage)
  326. else
  327. EnhancedGetopt "$@" # Parse program args
  328. if [ -n "$ARG_S" ] && [ -z "$NB_ARG" ]
  329. then
  330. ARG_V="y" # set also default for --short when single arg
  331. fi
  332. fi
  333. # Update args to All if requested
  334. if [ -n "$ARG_A" ]
  335. then
  336. [ -z "$ARG_C" ] && ARG_C="y"
  337. [ -z "$ARG_D" ] && ARG_D="y"
  338. [ -z "$ARG_I" ] && ARG_I="y"
  339. [ -z "$ARG_R" ] && ARG_R="y"
  340. [ -z "$ARG_V" ] && ARG_V="y"
  341. fi
  342. # Initialization
  343. GetLSBInfo
  344. GetDistribInfo
  345. # Display requested infos (order as follow)
  346. [ -n "$ARG_V" ] && DisplayVersion
  347. [ -n "$ARG_I" ] && DisplayID
  348. [ -n "$ARG_D" ] && DisplayDescription
  349. [ -n "$ARG_R" ] && DisplayRelease
  350. [ -n "$ARG_C" ] && DisplayCodename
  351. [ -n "$ARG_S" ] && echo "$MSG_RESULT"
  352. exit $EXIT_STATUS