Programmatically determining Ubuntu distribution and architecture? - linux

What's the best way to programmatically determine if the current machine is running Ubuntu, what architecture it has, and what version of Ubuntu it is running?
One way would be to scan the output of uname -a to check for the right kernel version and architecture.
Another way would be to scan /etc/apt/sources.list for the Ubuntu distribution keyword (eq precise, quantal, etc)
Is there a better way?

Apart from uname -a, There are several way to get information about the current distribution.
The best way is to parse the release files. They usually ended with -release or _release and located in /etc. Following command will find them all.
ls /etc/*{-,_}release
Ubuntu uses lsb_release
Redhat/Fedora uses redhat-release
Slackware uses slackware-release
Gentoo uses gentoo-release
Debian's corresponding file is /etc/debian_version. This file will also (somewhat misleadingly, but for a good reason) be present on Ubuntu systems, though.
Another file is /etc/issue which is used for machine identification and pre-login prompt can be used to determine current distribution information.
System information can be found in /proc/version too.
cat /proc/version

One way would be to scan the output of uname -a to check for the right kernel version and architecture.
But one does not generally want to parse the output of such tools, because it's not elegant (it's considered a hack, so to say).
However, you can use the uname() function/syscall:
#include <sys/utsname.h>
struct utsname sysinfo;
if (uname(&sysinfo) < 0) {
printf("Cannot determine OS\n");
exit(-1);
}
printf("Operating system name: %s\n", sysinfo.sysname);

You can use a library as a neutral to the operating system. A solution is lsband your question became close to using lsb question.

Afaik most Linux distributions also use /etc/issue. The text in it can ofcourse have been changed by the admin to show a different login message.
Sample from fedora:
Fedora release 17 (Beefy Miracle)
Kernel \r on an \m (\l)
Sample from ubuntu:
Ubuntu 11.04 \n \l

Related

Adding kernel module to Debian

I have imx6-quad and Debian Jessie installed on it. Here is the full info about (uname -a):
Linux linaro-alip 4.1.15-g5599520 #1 SMP PREEMPT Sun Jan 8 13:03:20 IST 2017 armv7l GNU/Linux
I'm trying to run tunslip application for CC1350 Launchpad, but there is no kernel module "tun" in my OS. When I run command modprobe tun, I given an error:
modprobe: FATAL: Module tun not found.
At this point, I don't know how to install tun module to my Debian. I even don't know where to start. Is it possible to add tun module to running operation system or should I compile whole kernel from scratch? If I can add kernel module, how could I add to running OS?
Any help is too precious for me.
So, to sum up the discussion in the comments in case someone else will come here with the same problem:
Unfortunately, the precompiled kernel image provided by Variscite here doesn't come with tun support at all. Neither in modules nor compiled into the kernel.
If you want tun support, you will have to compile the kernel in your own. Sources can be found here on github.
Previous Answer:
Since I'm not allowed to comment yet, please take this less as an answer but more as a suggestion where to look for a solution.
What does the following command give you?
cat /boot/config-4.1.15-g5599520 | grep CONFIG_TUN
It should say CONFIG_TUN=m. If it doesn't, it may be that your kernel already supports tun devices.
Have you tried searching for tunmodules in /lib/modules? If not, run
find /lib/modules/ -name '*tun.ko*'
and let us know what it gives you.
as you are building your kernel. there are a couple of methods one is to compile the module separately and to install it on the existing image. The other is to create the tun module along with the kernel and the sdcard image creation will take care of your module.
TO build tun module. use menuconfig from the kernel folder. search for something matching to CONFIG_TUN if its is a module change its value to m. Rebuild and create the sdcard again. This is the easy way.
You can also craete the module separately and then bring the module to your filesystem but that can be more error prone.

how to have linux kernel export /proc/[pid]/io?

Im running linux on my board and have to read info in /proc/[pid]/io. But it is not found.
For ex:
$ dd if=/dev/zero of=/tmp/aa &
[1] 926
$ cat /proc/926/io
cat: /proc/926/io: No such file or directory
Which I need enable to have kernel export that?
Many thanks for your help!
I just discovered that another thing is necessary.
I just recompiled a 4.4 kernel (for an embedded system) and enabling the CONFIG_TASKSTATS was not enough. I have to enable
CONFIG_TASKSTATS=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
in order for the /proc/<pid>/io to appear.
According to this, you need CONFIG_TASKSTATS enabled in your kernel.
You can check your current kernel's config in various ways depending on distribution, but looking at /boot/config-$(uname -r) works in Redhat flavors.
If you don't have that option configured, you'll need to recompile your kernel, or investigate why your distro doesn't enable it.

On which Linux Distributions do the "stat" and "service" commands run?

On which Linux Distributions do the following commands run?
service $servicename status
stat -c \"%a\" /var/log/$filename
For example assuming $servicename="apache2" and $filename="syslog".
stat is part of coreutils and part of the GNU project. Any major GNU/Linux distribution will offer this package. Note that minimal environments like BusyBox may instead offer their own, limited version of stat.
service is part of sysvinit-tools and not part of GNU. Only distributions using System-V-style init scripts will offer it.
Distrowatch offers a comparison of different distributions and also tracks the versions of a selected set of packages.
Note that services may have different names accross distributions as well. For example apache2 may be called httpd instead.

Determine OS from a single command line operation

Introduction:
I have a 'magic' tool that can perform a command line operation on a machine if I provide the IP.
The tool knows the OS that machine is using and executes the command on cmd/shell based on whether it is windows/linux and returns the output of the command back blindly.
C:> tool.exe 172.140.56.2 "ipconfig"
Assumptions:
One OS per machine. Tool has no problem executing the command (whether it fails or not is a different problem)
The OS is either windows or linux always.
I determine the OS based on the command result
Problem:
Using this power of being able to execute a command, I want to determine the OS
My Solution:
Execute ipconfig command. If result is
-bash: ipconfig: command not found
It is linux.
Else if it is like this:
Windows IP Configuration
Ethernet adapter Local Area Connection:
...
then Windows.
Question:
I wanted to know if this is a foolproof way of doing this. I want a command which would not fail under certain scenarios. (say cygwin installed on windows allowing linux commands to succeed. Or ipconfig succeeding on linux under some special scneario.)
I can process the command output with some parser, if that helps in any way.
Just to clear any confusion. It can be ANY command. I ust used ipconfig in my example.
If I understood your problem correctly, then uname is the ideal command. If it's any Unix-system (including OSX), it'll return the correct variable, and if it's Windows it'll return command not found or similar.
Safest way to determine Linux/version is
cat /etc/*release
Sample output.
DISTRIB_ID=LinuxMint
DISTRIB_RELEASE=17
DISTRIB_CODENAME=qiana
DISTRIB_DESCRIPTION="Linux Mint 17 Qiana"
NAME="Ubuntu"
VERSION="14.04.1 LTS, Trusty Tahr"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 14.04.1 LTS"
VERSION_ID="14.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
Another command that should work is set, which displays name and value of each environment variable. Any shell on Linux supports it (although output is different between csh and bash). Output from a Windows system would have PROCESSOR_ARCHITECTURE and other standard variables in it (see https://ss64.com/nt/syntax-variables.html), which are very unlikely to be set in Linux.

How to detect if my server is running centos or other from a perl script

I want to display some text in a script only if the Operating System is Centos .
How can i do that in a perl script ?
To answer your exact question, you can identify CentOS by reading the contents of /etc/redhat-release. E.g.
$ cat /etc/redhat-release
CentOS release 5.9 (Final)
As other commenters have made clear, it is better to depend on the exact OS features you want, or write code to be portable, rather than limiting it to a particular distribution of Linux.
Try $^O. It contains the OS that was used to build your version of Perl. Here's what perlvar has to say about it.
The name of the operating system under which this copy of Perl was
built, as determined during the configuration process. For examples
see PLATFORMS in perlport. The value is identical to $Config{'osname'}
. See also Config and the -V command-line switch documented in
perlrun. In Windows platforms, $^O is not very helpful: since it is
always MSWin32 , it doesn't tell the difference between
95/98/ME/NT/2000/XP/CE/.NET. Use Win32::GetOSName() or
Win32::GetOSVersion() (see Win32 and perlport) to distinguish between
the variants. This variable was added in Perl 5.003.
Also see perlport.

Resources