How to determine whether a given Linux is 32 bit or 64 bit? - linux

When I type uname -a, it gives the following output.
Linux mars 2.6.9-67.0.15.ELsmp #1 SMP Tue Apr 22 13:50:33 EDT 2008 i686 i686 i386 GNU/Linux
How can I know from this that the given OS is 32 or 64 bit?
This is useful when writing configure scripts, for example: what architecture am I building for?

Try uname -m. Which is short of uname --machine and it outputs:
x86_64 ==> 64-bit kernel
i686 ==> 32-bit kernel
Otherwise, not for the Linux kernel, but for the CPU, you type:
cat /proc/cpuinfo
or:
grep flags /proc/cpuinfo
Under "flags" parameter, you will see various values: see "What do the flags in /proc/cpuinfo mean?"
Among them, one is named lm: Long Mode (x86-64: amd64, also known as Intel 64, i.e. 64-bit capable)
lm ==> 64-bit processor
Or using lshw (as mentioned below by Rolf of Saxony), without sudo (just for grepping the cpu width):
lshw -class cpu|grep "^ width"|uniq|awk '{print $2}'
Note: you can have a 64-bit CPU with a 32-bit kernel installed.
(as ysdx mentions in his/her own answer, "Nowadays, a system can be multiarch so it does not make sense anyway. You might want to find the default target of the compiler")

If you were running a 64 bit platform you would see x86_64 or something very similar in the output from uname -a
To get your specific machine hardware name run
uname -m
You can also call
getconf LONG_BIT
which returns either 32 or 64

lscpu will list out these among other information regarding your CPU:
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
...

Another useful command for easy determination is as below:
Command:
getconf LONG_BIT
Answer:
32, if OS is 32 bit
64, if OS is 64 bit

The command
$ arch
is equivalent to
$ uname -m
but is twice as fast to type

I was wondering about this specifically for building software in Debian (the installed Debian system can be a 32-bit version with a 32 bit kernel, libraries, etc., or it can be a 64-bit version with stuff compiled for the 64-bit rather than 32-bit compatibility mode).
Debian packages themselves need to know what architecture they are for (of course) when they actually create the package with all of its metadata, including platform architecture, so there is a packaging tool that outputs it for other packaging tools and scripts to use, called dpkg-architecture. It includes both what it's configured to build for, as well as the current host. (Normally these are the same though.) Example output on a 64-bit machine:
DEB_BUILD_ARCH=amd64
DEB_BUILD_ARCH_OS=linux
DEB_BUILD_ARCH_CPU=amd64
DEB_BUILD_GNU_CPU=x86_64
DEB_BUILD_GNU_SYSTEM=linux-gnu
DEB_BUILD_GNU_TYPE=x86_64-linux-gnu
DEB_HOST_ARCH=amd64
DEB_HOST_ARCH_OS=linux
DEB_HOST_ARCH_CPU=amd64
DEB_HOST_GNU_CPU=x86_64
DEB_HOST_GNU_SYSTEM=linux-gnu
DEB_HOST_GNU_TYPE=x86_64-linux-gnu
You can print just one of those variables or do a test against their values with command line options to dpkg-architecture.
I have no idea how dpkg-architecture deduces the architecture, but you could look at its documentation or source code (dpkg-architecture and much of the dpkg system in general are Perl).

#include <stdio.h>
int main(void)
{
printf("%d\n", __WORDSIZE);
return 0;
}

If you have a 64-bit OS, instead of i686, you have x86_64 or ia64 in the output of uname -a. In that you do not have any of these two strings; you have a 32-bit OS (note that this does not mean that your CPU is not 64-bit).

That system is 32bit. iX86 in uname means it is a 32-bit architecture. If it was 64 bit, it would return
Linux mars 2.6.9-67.0.15.ELsmp #1 SMP Tue Apr 22 13:50:33 EDT 2008 x86_64 i686 x86_64 x86_64 GNU/Linux

Nowadays, a system can be multiarch so it does not make sense anyway. You might want to find the default target of the compiler:
$ cc -v 2>&1 | grep ^Target
Target: x86_64-pc-linux-gn
You can try to compile a hello world:
$ echo 'int main() { return 0; }' | cc -x c - -o foo
$ file foo
foo: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=b114e029a08abfb3c98db93d3dcdb7435b5bba0c, not stripped

With respect to the answer "getconf LONG_BIT".
I wrote a simple function to do it in 'C':
/*
* check_os_64bit
*
* Returns integer:
* 1 = it is a 64-bit OS
* 0 = it is NOT a 64-bit OS (probably 32-bit)
* < 0 = failure
* -1 = popen failed
* -2 = fgets failed
*
* **WARNING**
* Be CAREFUL! Just testing for a boolean return may not cut it
* with this (trivial) implementation! (Think of when it fails,
* returning -ve; this could be seen as non-zero & therefore true!)
* Suggestions?
*/
static int check_os_64bit(void)
{
FILE *fp=NULL;
char cb64[3];
fp = popen ("getconf LONG_BIT", "r");
if (!fp)
return -1;
if (!fgets(cb64, 3, fp))
return -2;
if (!strncmp (cb64, "64", 3)) {
return 1;
}
else {
return 0;
}
}
Good idea, the 'getconf'!

You can also check using a environment variable:
echo $HOSTTYPE
Result:
i386 -> 32 bits
x86_64 -> 64 bits
Extracted from: http://www.sysadmit.com/2016/02/linux-como-saber-si-es-32-o-64-bits.html

In Bash, using integer overflow:
if ((1 == 1<<32)); then
echo 32bits
else
echo 64bits
fi
It's much more efficient than invoking another process or opening files.

getconf uses the fewest system calls:
$ strace getconf LONG_BIT | wc -l
253
$ strace arch | wc -l
280
$ strace uname -m | wc -l
281
$ strace grep -q lm /proc/cpuinfo | wc -l
301

If you shift 1 left by 32 and you get 1, your system is 32 bit.
If you shift 1 left by 64 and you get 1, your system is 64 bit.
In other words,
if echo $((1<<32)) gives 1 then your system is 32 bit.
if echo $((1<<64)) gives 1 then your system is 64 bit.

If one is severely limited in available binaries (e.g. in initramfs), my colleagues suggested:
$ ls -l /lib*/ld-linux*.so.2
On my ALT Linux systems, i586 has /lib/ld-linux.so.2 and x86_64 has /lib64/ld-linux-x86-64.so.2.

$ grep "CONFIG_64" /lib/modules/*/build/.config
# CONFIG_64BIT is not set

I can't believe that in all this time, no one has mentioned:
sudo lshw -class cpu
to get details about the speed, quantity, size and capabilities of the CPU hardware.

Simple script to get 64 bit or 32 bit
if $(getconf LONG_BIT | grep '64'); then
echo "64 bit system"
else
echo "32 bit system"
fi

[ -z `uname -m | grep 64` ] && echo "32-bit" || echo "64-bit"
Based on the fact that 64-bit is usually x86_64 and 32-bit is i686 etc.

First you have to download Virtual Box. Then select new and a 32-bit Linux. Then boot the linux using it. If it boots then it is 32 bit if it doesn't then it is a 64 bit.

Related

How do I know what linux kernel version does a distribution use?

When I run
uname -r
I get 3.2.0-4-686-pae on my Debian7 and 4.4.26-gentoo on my Gentoo.
But what I can't find anywhere is what Linux kernel source versions do these distributions use. If I understand right all distributions take the kernel source code from here https://www.kernel.org. So how can I find out what Linux kernel versions from the site do use 4.4.26-gentoo or 3.2.0-4-686-pae, for example?
Try man uname and find -v for the kernel version used. ;)
So it is uname -v or uname -a if you just dont care about specifics and want to see it all. :p
$ uname -v
#1 SMP Debian 3.16.36-1+deb8u2 (2016-10-19)
$ uname -a
Linux Phobos 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u2 (2016-10-19) x86_64 GNU/Linux
Check out the difference between the uname -r part and the uname -v part in uname -a (the first version number in -a)
$ uname -r
3.16.0-4-amd64
you have some way to know linux kernel version :
good way
uname -r
bad way to see kernel version ( you should see version of vmlinu* initrd files if they have version number of kernel )
ls /boot | grep "vmlinu*"; ls /boot | grep "initrd*"
you can try this way to know all of kernel versions on your machine :
ls /lib/modules/
uname -r is the easiest way.
though there are utilities like screenfetch or neofetch that give you more information in a clear and pretty manner.
Just run screenfetch and it'll display details.
(screenfetch is usually pre-installed on most distros these days).
If it is not installed, just run sudo apt install screenfetch (on debian based distros like ubuntu) or sudo pacman -S screenfetch ( on Arch based distros.
If you are looking for original Linux kernel version that matches browse-able
https://elixir.bootlin.com/linux/vx.y.z/
or LINUX_KERNEL_CODE you check when developing kernel code, "uname" is not the right answer!
There are two methods (I use my Ubuntu 16.04 as example):
dmesg
dmesg | grep "Linux\ version"
[ 0.000000] Linux version 4.4.0-210-generic (buildd#lgw01-
amd64-009) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-
6ubuntu1~16.04.12) ) #242-Ubuntu SMP Fri Apr 16 09:57:56 UTC 2021
(Ubuntu 4.4.0-210.242-generic 4.4.262)
The original kernel version is 4.4.262! And 4.4.0-210-generic is Ubuntu's kernel number.
Install the kernel source use command like
sudo apt-get install linux-source
Look at the newly installed file ('uname -r' => 4.4.0-210-generic)
/lib/modules/4.4.0-210-generic/build/include/generated/uapi/linux/version.h
#define LINUX_VERSION_CODE 263423
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
That version code is 0x0404FF indicating 4.4.[>=255] (where FF is for when patch exceeds 255).
-------- interesting reading below--------
It is interesting to look at the file
/lib/modules/4.4.0-210-generic/build/include/generated/utsrelease.h
#define UTS_RELEASE "4.4.0-210-generic"
#define UTS_UBUNTU_RELEASE_ABI 210
Now we know where uname and /proc/version get their number.
On my Ubuntu 20.04 5.4.0-80-generic
dmesg | grep "Linux\ versin"
[ 0.000000] Linux version 5.4.0-80-generic (buildd#lcy01-
amd64-030) (gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04))
#90-Ubuntu SMP Fri Jul 9 22:49:44 UTC 2021
(Ubuntu 5.4.0-80.90-generic **5.4.124**)
and LINUX_KERNEL_CODE is
$ cat /lib/modules/5.4.0-80-generic/build/include/generated/uapi/linux/version.h
#define LINUX_VERSION_CODE 328828
where 328828 = 0x05047C, indicating 5.4.124.

Check Which operating system is installed ( CentOS, Ubuntu, Redhat, ... etc)

I have been given a server with OS installed. I want to check which Operating system is installed in it. I have used uname -a with ouput of
Linux ctl 2.6.32-573.3.1.el6.x86_64 #1 SMP Mon Aug 10 09:44:54 EDT 2015 x86_64 x86_64 x86_64 GNU/Linux
Any suggestions ?
You could use the /etc/os-release file, which contains information on the os using the freedesktop spec.
Printing out just the OS name and version:
awk -F '=' '/PRETTY_NAME/ { print $2 }' /etc/os-release
Using os-release file available in Linux:
cat /etc/os-release
on many OS's, you can get the os via:
lsb_release -d
The el6 in the kernel version could indicate a RedHat (thus Fedora as well), Oracle, Centos, Scientific Linux. Potentially others as well.
At least on some of these systems (others as well) the distribution can be identified from the /etc/issue* files. For example:
> ls -la /etc/issue*
-rw-r--r-- 1 root root 57 Oct 22 2014 /etc/issue
-rw-r--r-- 1 root root 55 Oct 22 2014 /etc/issue.net
> cat /etc/issue
Welcome to openSUSE 13.2 "Harlequin" - Kernel \r (\l).
you can try this command to check all detail related to operating system version:
cat /etc/*elease

Hung process and Linux syscall 248?

I'm troubleshooting a hung self test for the upcoming OpenSSL 1.1.0 on a particular machine. I've tried to debug this issue twice, and it resulted in two unresponsive GDB's and two hung processes:
$ ps -A | grep afalgtest
1030 pts/0 00:00:00 afalgtest
1196 pts/0 00:00:00 afalgtest
I was able to kill GDB, but I was not able to kill the hung processes.
According to /proc/<pid>/syscall, both are in syscall 248:
via:test$ sudo cat /proc/1030/syscall
248 0xb7fd6000 0x1 0xbfff98d4 0xb7fb9270 0xbfff98e0 0xb7ec45f7 0xbfff986c 0xb7fdbbe8
via:test$ sudo cat /proc/1196/syscall
248 0xb7fd6000 0x1 0xbfff98d4 0xb7fb9270 0xbfff98e0 0xb7ec45f7 0xbfff986c 0xb7fdbbe8
I'm running a machine with the VIA C7-D processor, and it needs Lubuntu 15 because its one of the few distros to support VIA's PM400 graphics chipset. Lubuntu 15 uses the 4.2 kernel:
$ uname -a
Linux via 4.2.0-30-generic #36-Ubuntu SMP Fri Feb 26 00:57:19 UTC 2016 i686 i686 i686 GNU/Linux
The next step is:
$ cat /usr/include/asm-generic/unistd.h | grep 248
$
Which returns nothing. Next, cat'ing unistd.h:
...
/*
* Architectures may provide up to 16 syscalls of their own
* starting with this value.
*/
#define __NR_arch_specific_syscall 244
#define __NR_wait4 260
__SC_COMP(__NR_wait4, sys_wait4, compat_sys_wait4)
#define __NR_prlimit64 261
__SYSCALL(__NR_prlimit64, sys_prlimit64)
#define __NR_fanotify_init 262
__SYSCALL(__NR_fanotify_init, sys_fanotify_init)
#define __NR_fanotify_mark 263
...
Just in case 248 is 0x248:
$ cat /usr/include/asm-generic/unistd.h | grep 584
$
So my question is, how can I determine which syscall the process is hung in?
It appears I have the latest kernel headers:
$ sudo apt-get install linux-headers-$(uname -r)
Reading package lists... Done
Building dependency tree
Reading state information... Done
linux-headers-4.2.0-30-generic is already the newest version.
linux-headers-4.2.0-30-generic set to manually installed.
The syscall number is decimal. Syscall table you are looking for can be found in arch/x86/entry/syscalls/syscall_32.tbl. Regardless, you are inspecting the wrong file. What you want to see is the entire backtrace provided in /stack file. The kernel is nice enough to not only unwind the stack but also resolve all symbols. Alternatively you can use a debugger (named crash) to inspect the live kernel.

Delete files with a similar names, matching a range

I have multiple similarly named file. The difference in their name is just an incremented number. For example linux kernels:
rc linux-image-3.2.0-29-generic 3.2.0-29.46 Linux kernel image for version 3.2.0 on 64 bit x86 SMP
rc linux-image-3.2.0-31-generic 3.2.0-31.50 Linux kernel image for version 3.2.0 on 64 bit x86 SMP
rc linux-image-3.2.0-32-generic 3.2.0-32.51 Linux kernel image for version 3.2.0 on 64 bit x86 SMP
rc linux-image-3.2.0-33-generic 3.2.0-33.52 Linux kernel image for version 3.2.0 on 64 bit x86 SMP
rc linux-image-3.2.0-34-generic 3.2.0-34.53 Linux kernel image for version 3.2.0 on 64 bit x86 SMP
rc linux-image-3.2.0-35-generic 3.2.0-35.55 Linux kernel image for version 3.2.0 on 64 bit x86 SMP
.... and more of them
I would like to remove most of them. Say, from 29 to 35. There are too much to remove manually using sudo apt-get purge linux-image-x.x.x.x-generic. What script should I write?
You can delete files based on its name pattern. For example, do:
rm linux-image-3.2.0-{29..35}-generic
Before, and to make sure you are deleting the right thing, do execute the command with ls to see which files will be affected.
If this is your first line:
rc linux-image-3.2.0-01-generic 3.2.0-29.46
and this is your 40th line:(for example)
rc linux-image-3.2.0-40-generic 3.2.0-29.46
So you can use awk to delete specific lines:
awk -v m=29 -v n=35 'm <= NR && NR <= n {next} {print}' test.txt

Finding if kernel is 32-bit or 64-bit on Linux

When I run uname -a, I get:
Linux 2.6.18-164.el5 #1 SMP Tue Aug 18 15:51:48 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
and I understand that x86_64 is supposed to imply 64-bit kernel, but why does this number appear 3 times? What does each instance signify?
Uname has separate commands to print "machine, processor and hardware platform" -- all of these are all the same in your case. The following outputs, respectively, may make it clear:
~$ uname -m # print machine
x86_64
~$ uname -p # print processor
x86_64
~$ uname -i # print hw platform
x86_64
use uname -m command to display only name of the kernel.
in your case
uname -m
x86_64
means 64-bit
uname -a
will give you all details about your system. It includes machine hardware name, processor type & hardware platform too.
So,
x86_64 is machine name.
x86_64 is processor type.
x86_64 is hardware platform.
Use:
uname --help
to get more idea about its options.

Resources