Better way to check linux version? - linux

What I currently have. Is this the best way? Have a script with lots of functions and need a way to know what OS is running before running each function.
CHECK_architecture()
{
architecture=`uname -m`
if [ "$architecture" != "x86_64" ] && [ "$architecture" != "ia64" ]; then
architecture="x86"
else
architecture="x86_64"
fi
}
CHECK_distro()
{
DISTRO="";
if [ `uname -r | egrep '(6.2-RELEASE|6.1-RELEASE|5.5-RELEASE|6.1-STABLE|5.4-RELEASE|6.0-RELEASE|5.3-RELEASE|4.10-RELEASE|4.11-RELEASE)'` ]; then
DISTRO="FreeBSD";
$BIN_ECHO " System is running FreeBSD"
elif [ -f /etc/debian_version ]; then
$BIN_ECHO " System is running Debian Linux"
DISTRO=DEBIAN;
elif [ -f /etc/SuSE-release ]; then
$BIN_ECHO " System is running SuSE Linux"
DISTRO=SUSE;
elif [ -f /etc/fedora-release ]; then
$BIN_ECHO " System is running Fedora Linux"
DISTRO=FEDORA;
elif [ -f /etc/redhat-release ]; then
$BIN_ECHO " System is running Red Hat Linux"
DISTRO=REDHAT;
else
$BIN_ECHO -e " no supported distribution found running "
exit 1
fi
}

From the Linux Standard Base article at wikipedia:
The Linux Standard Base (LSB) is a joint project by several Linux distributions under the organizational structure of the Linux Foundation to standardize the software system structure, including the filesystem hierarchy, used with Linux operating system. The LSB is based on the POSIX specification, the Single UNIX Specification, and several other open standards, but extends them in certain areas.
According to the LSB:
The goal of the LSB is to develop and promote a set of open standards that will increase compatibility among Linux distributions and enable software applications to run on any compliant system even in binary form. In addition, the LSB will help coordinate efforts to recruit software vendors to port and write products for Linux Operating System.
If you are using some LSB compliant distribution (and you should), just man lsb_release:
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 8.04.4 LTS
Release: 8.04
Codename: hardy
$ lsb_release -a
LSB Version: :core-3.1-amd64:core-3.1-ia32:core-3.1-noarch:graphics-3.1-amd64:graphics-3.1-ia32:graphics-3.1-noarch
Distributor ID: CentOS
Description: CentOS release 5.5 (Final)
Release: 5.5
Codename: Final

You are looking for the config.guess utility. It will reliably determine the architecture and OS, and give you a standardized moniker which many other tools use. It will not tell you precisely which Linux distribution you have, but you should not need that information -- please explain what you are using it for, and I can give further advice.

There isn't an absolutely reliable way to check the Linux distribution and its version.
$ head -n1 /etc/issue

Actually, it depends on the type of linux OS you are running. To me, best way to get the version of linux you are on is from /etc/redhat-release if you are on Redhat. For other,
Redhat: Test for /etc/redhat-release, check contents
Debian: Test for /etc/debian_version, check contents
Mandriva: Test for /etc/version, check contents
Slackware: Test for /etc/slackware-version, check contents
Generally speaking, check for /etc/*-release and /etc/*-version

Probably most correct and easiest way is to follow Free Standards Group, and use lsb-release: http://linux.die.net/man/1/lsb_release

Related

How to check if Linux user namespaces are supported by current OS kernel

After doing some reading, I found that Linux user namespaces are generally supported in Linux versions >= 3.8. However, there's a possibility that user namespaces are disabled on a given OS, making the check for kernel versions unreliable. Is there a robust way to check if the current OS I'm using supports user namespaces and has it available to use?
You could check if your current process' /proc/[pid]/ns/ directory has a file called user:
ls /proc/self/ns
There are two places you can check to see if your kernel supports user namespaces:
/boot/config-*. (find out which one you are actually using with uname -a)
/proc/config.gz.
In both files look for CONFIG_USER_NS. If it reads CONFIG_USER_NS=y you're golden. If not, well, you're about to compile a new kernel.
Provided you are running bash (you can check by running echo $0, expected result is -bash). Then you can run the following one liner:
if [[ `sudo cat /boot/config-$(uname -a | awk '{print $3}') |grep '^CONFIG_USER_NS'` == "CONFIG_USER_NS=y" ]]; then echo "You have support for User Namespaces"; else echo "Sorry, you don't have support for User Namespaces"; fi

How to check for 32-bit / 64-bit kernel for Linux

I need to write a bash script where i have to check whether the Linux kernel is 32 bit or 64 bit.
I am using uname -a command, and it gives me x86_64 result. But I believe I can not use it in the generic way because result may differ if some one using non x86 architecture.
How to check for 32-bit / 64-bit kernel for Linux?
The question is rather: what do you intend to achieve by knowing whether you are on 32 or 64? What are the consequences of being on a hypothetical 128-bit environment? And what part actually is being tested for N-bitness? A CPU may support running in 64-bit mode, but the environment be 32-bit. Furthermore, the environment itself may be a mixed-mode; consider running a 64-bit kernel with a 32-bit userspace (done on a handful of classic RISCs). And then, what if the userspace is not of a homogenous bitness/executable format? That is why getconf LONG_BIT is equally pointless to use, because it depends on how it was compiled.
$ /rt64/usr/bin/getconf LONG_BIT
64
$ /usr/bin/getconf LONG_BIT
32
$ file /usr/bin/getconf /rt64/usr/bin/getconf
/usr/bin/getconf: ELF 32-bit MSB executable, SPARC32PLUS, V8+ Required, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.4, not stripped
/rt64/usr/bin/getconf: ELF 64-bit MSB executable, SPARC V9, relaxed memory ordering, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.4, not stripped
$ uname -m
sparc64
You could query the system for the size of a long int:
getconf LONG_BIT
But I'm not sure if this is completely portable to all different architectures.
I came up with the following. It assumes that init is used (some distros have switched to other loaders, but it should be easy to get a list of reasonably often used ones) and that you use ELF, not a.out or other nowadays exotic executable format. These seem to be sane assumptions for most systems, but probably they may be broken in embedded systems, etc. Still, the general idea should be possible to adapt (get to the init process or equivalent and check its bitness using file). If you are running as root, instead of going through the file's path, you could use file $(sudo readlink -e /proc/1/exe) (PID 1 being init is probably more portable than assuming anything about its path).
if file /sbin/init | fgrep 'ELF 64-bit' &>/dev/null; then
echo "64-bit"
else
echo "not 64-bit"
fi
Search for the lm (long mode) flag in /proc/cpuinfo. If this is true, it means you have a 64 bit processor. A simple grep should give you this information.
Regarding the kernel version, you can always grep on the uname -a information. Better would be to find the source of the uname program so that we can discount the discrepancy due to malicious hostname.
A quite reliable way to determine the supported executable architecture:
A featured function to do this:
# Gets the supported executable architecture
# >: 32-bit | 64-bit
getRunArch() {
local arch
local IFS=' '
read -r _ arch _ <<< $(file --dereference --brief "$(which ls)")
echo -n "${arch}"
}
Testing this:
echo "Supported run-time architecture is: $(getRunArch)"
Supported run-time architecture is: 64-bit
Slightly more reliable than:
getconf LONG_BIT
Depend what you're looking for, I have machine installed in 32 bit on 64 bit proc, all of above would return 32 bit in my case
But if I look at hardware, lshw on Ubuntu (lshw -c cpu), the description of cpu clearly show I have a 64 bit CPU, so I could have install a 64 bit version of Ubuntu.
/proc/cpuinfo is also good source of info about hardware, like the lm flags stand for long mode.
Have a nice day.
Jack.
Grep for '64' in uname output
uname -a | grep 64

Linux: list all available window managers

How do I get a list of all available windows managers on a linux system (Of course this would mostly not be needed but - I don't have root permissions).
Very difficult to search on Google as all results returned are for "list of window managers for linux".
Clarification: I am looking for a command that lists "All window managers that are installed" on the system that I am working on.
Interested to know it's distro dependent. My distro is RedHat.
cat /proc/version
(Linux version 2.4.21-40.ELsmp (centos#sillage.bis.pasteur.fr) (gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-53)) #1 SMP Wed Mar 15 13:46:01 EST 2006)
It really depend on your particular distribution or OS.
Say, on debian and ubuntu one uses:
$ update-alternatives --list x-window-manager
/usr/bin/twm
/usr/bin/fvwm2
/usr/bin/beryl
/usr/bin/beryl-xgl
/usr/bin/icewm
/usr/bin/kwin
/usr/bin/wmaker
A couple more places I found on Debian:
grep "^Exec" /usr/share/xsessions/*
grep -l "section=.Window Managers." /usr/share/menu/*
(In the second, we may want to check the command= part of each file.)
And on an old Gentoo I noticed:
find /etc/X11/Sessions/* -printf '%f\n'
Depends on your distribution/package manager. Most package managers will probably not even have a category "window managers".
Anyway, in gentoo you'd do:
$ eix -I -C x11-wm --only-names
x11-wm/enlightenment
x11-wm/twm
On Slackware there is nice xwmconfig, but I'm not sure if it exists on other distributions.

killproc and pidofproc on linux

I have a script which uses killproc and procofpid commands and executes fine on a 64bit suse. But when I executed the script on 32bit redhat , I found that the above commands donot exist.
I don't have a 32bit Suse and 64bit redhat machines to test my script.
Is my guess right that on 64bit redhat the above commands should be available?
Or are the above commands specific to Suse and redhat?
Thanks
killproc is in redhat enterprise linux 5.4 as part of /etc/init.d/functions
if you need it just do
. /etc/init.d/functions
in your script to load the shell functions, its probably in other versions of redhat but thats the only one i have to hand at the moment
These commands are defined as part of the Linux Standards Base (LSB), as noted by #AndreKR.
However, on some systems like Redhat (and probably SUSE), depending on packages installed, these functions may not be defined in the location specified by the LSB, which is /lib/lsb/init-functions. Rather they are defined within /etc/init.d/functions. In addition, in some versions, the Redhat variant of /etc/init.d/functions is missing the LSB-defined function start_daemon. If you add the following snippet to the top of your script, it should be portable across most distributions/installs:
if [[ -f /lib/lsb/init-functions ]]; then
. /lib/lsb/init-functions
elif [[ -f /etc/init.d/functions ]]; then
. /etc/init.d/functions
# Pretend to be LSB-compliant
function start_daemon() {
daemon $*
}
else
echo "Linux LSB init function script or Redhat /etc/init.d/functions is required for this script."
echo "See http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptfunc.html"
exit 1
fi
The commands are unlikely to be portable. Actually this is first time I hear about them - but I guess your problem is to work with process by the name, not pid.
Check the man pgrep or man pkill - they are slightly bit more portable. They are part of procps package (where ps and top come from) and should be available on all Linux variants. They are also available on Solaris.
The ones used in Ubuntu are part of the specification "Linux Standard Base" and are documented there.
I think those commands are distrib specifics: I have never seen them before.
killproc should be a kind of kill but what is procofpid supposed to do?
In the title you speak about pidofproc, you can find this command under the pidof on most linux boxes.
I had the same problem as you, it gave the warning:
pidof: invalid options on command line!
I changed the
"killproc -d 10 $cmd"
to
"kill -9 \`pidof $cmd\`"

How to get Linux distribution name and version?

In Windows I read the registry key SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductName to get the full name and version of the OS.
But in Linux, the code
struct utsname ver;
uname(&ver);
retVal = ver.sysname;
returns the string linux, not Ubuntu 9.04.
How can I get the Linux distribution name and version?
Try:
cat /etc/lsb-release
You can also try
lsb_release -a
Or:
cat /proc/version
lsb_release -ds ; uname -mr
on my system yields the following from the bash (terminal) prompt:
Ubuntu 10.04.4 LTS
2.6.32-41-generic x86_64
trying this way is an interesting one and less restrictive than lsb-release.
$ cat /etc/*-release
What's the purpose of getting that information?
If you're trying to detect some features or properties of the system (e.g. does it support some syscall or does it have some library), instead of relying on output of lsb_release you should either:
try to use given features and fail gracefully (e.g. dlopen for libraries, syscall(2) for syscalls and so on)
make it a part of your ./configure check if applicable (standard FOSS way of automatically recognizing system features/properties)
Note that the first way above applies even if your software is binary-only.
Some code examples:
dl = dlopen(module_path, RTLD_LAZY);
if (!dl) {
fprintf(stderr, "Failed to open module: %s\n", module_path);
return;
}
funcptr = dlsym(dl, module_function);
if (!funcptr) {
fprintf(stderr, "Failed to find symbol: %s\n", module_function);
return;
}
funcptr();
dlclose(dl);
You can even gracefully test for CPU opcodes support, read e.g. http://neugierig.org/software/chromium/notes/2009/12/flash-lahf.html , http://code.google.com/p/chromium/issues/detail?id=29789
Not sure I followed exactly what you're after but I think you just want the "all" flag on uname:
uname -a
/etc/os-release is available on at least both CentOS 7 and Ubuntu 16.04, which makes it more cross-platform than lsb_release (not on CentOS) or /etc/system-release (not on Ubuntu).
$ cat /etc/os-release
Example:
NAME=Fedora
VERSION="17 (Beefy Miracle)"
ID=fedora
VERSION_ID=17
PRETTY_NAME="Fedora 17 (Beefy Miracle)"
ANSI_COLOR="0;34"
CPE_NAME="cpe:/o:fedoraproject:fedora:17"
HOME_URL="https://fedoraproject.org/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
Usually:
cat /etc/issue
cat release file to display Linux distro version
$ cat /etc/*-release
lsb_release will return Linux distribution name and version
$ lsb_release -a
hostnamectl will return Linux distribution name and version
$ hostnamectl
To print certain system information
$ uname -a
or
-s, --kernel-name print the kernel name
-n, --nodename print the network node hostname
-r, --kernel-release print the kernel release
-v, --kernel-version print the kernel version
-m, --machine print the machine hardware name
-p, --processor print the processor type (non-portable)
-i, --hardware-platform print the hardware platform (non-portable)
-o, --operating-system print the operating system
To find out Static hostname, Chassis, Mchine ID, Virtualization, OS, Kernel, Architecture
$ cat /proc/version

Resources