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

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.

Related

Embedding version info in executable and retrieving it from Linux core dump?

I rely a lot on core dumps for finding and fixing rare bugs on my personal applications.
I have multiple versions of my applications installed side by side, and decide which one to run (it depends on some other applications). Only one version of the same tool can run at any given time. My launchers start with "ulimit -c unlimited". When/if the application crashes, a core dump is generated.
One issue is that "file somecoredump" tells me the name of the process generated the core file, but I have no way to know which version of the application generated it, so it's not easy to tell which executable to use.
I'm wondering how this issue can be solved?
I can think of a couple of bad ways:
Embed the version info into the process name, such as MyProcess2.1c. Now "file corefile" tells me the version. Really ugly, I won't consider it.
Every launcher modifies /proc/sys/kernel/core_pattern and sets it to a path with the version info, such as /var/crash/2.1c/core. Ugly, because this setting affects all apps, not just mine. Also it only works now because I only allow a single version of the app to run at the same time, one day I might need to run multiple versions side-by-side.
What would be ideal for me is if there was a way to embed version info into the executable, and retrieve it from the core file. Is this possible?
You can use the strings command in linux to look for unique strings in a binary file. Perhaps you can compile the version into the binary such as this examnple from bash and then grep all the strings output to find it. Just prefix it with a unique string to make it easier to find?:
~]$ strings /usr/bin/bash | grep version
shell_version_string
build_version
sccs_version
rl_library_version
rl_do_lowercase_version
show_shell_version
rl_readline_version
dist_version
GNU bash, version %s-(%s)
GNU bash, version %s (%s)
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
#(#)Bash version 4.2.46(2) release GNU
display-shell-version
-l do not print tilde-prefixed versions of directories relative
HOSTTYPE The type of CPU this version of Bash is running under.
OSTYPE The version of Unix this version of Bash is running on.
version, type `enable -n test'.
do-lowercase-version
.gnu.version
.gnu.version_r
~]$

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.

How to identify build architecture from packages?

I have a machine with Red Hat AS5. On it are installed two versions of a linux application called xmlsec. One is supposedly built for AS3 and the other, AS5. Is there any way to verify which is which? The file names provide this information but is there a way to look into the signature of the installed package to ensure accuracy?
In general, is there a way to determine the build architecture (OS) of a completed installation?
Let me know if I need to provide more information.
I'm still new to building and maintaining packages. Please direct me to some books or websites if my question doesn't make sense or I just need to gain more understanding.
Thanks.
How about it?
$rpm -q -a --queryformat='%{N}-%{V}-%{R}.%{arch}\n'
vsftpd-2.0.1-5.EL4.5.x86_64
hal-0.4.2-6.EL4.x86_64
Or Try this one
$rpm -q -a --queryformat '%{NAME}%{VERSION}%{RELEASE}\n'
xorg-x11-twm6.8.21.EL.18
hwbrowser0.190.EL4.4
Buildarch tag
$rpm -q --queryformat='%{N}-%{V}-%{R}.%{arch}.%{BUILDARCHS}\n' rpm
rpm-4.4.2.3-18.el5.x86_64.(none)
List of tags
$rpm --querytags
BUILDHOST
OS
POSTIN
POSTUN
FILELINKTOS
BUILDTIME
BUILDHOST
BUILDARCHS

Programmatically determining Ubuntu distribution and architecture?

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

Will Perl upgrade break older version on Linux?

I upgrade perl from perl58 to perl588 on Suse Linux.It looks that even though the Config.pm exists for the older version the newer version installation breaks the older version.While the upgrade of Perl on other OSes like HP and AIX does not disturb the older version.
For eg: The perl58 and perl588 versions are present in folder say "/usr/standard_perl" as follows:
/usr/standard_perl/perl58 (directory)
/usr/standard_perl/perl588 (directory)
and have symbolic links pointing to it.
Before and after upgrade the links are as follows:
Before:
perl58_link -> /usr/standard_perl/perl58
After:
perl5_link -> /usr/standard_perl/perl588
perl58_link -> /usr/standard_perl/perl588
perl588_link -> /usr/standard_perl/perl588
Now when i try to run simple "./perl -V" command from /usr/standard_perl/perl58/bin the older version complains of Config.pm not found even though its very well present in its own tree structure.
Is it that in Linux, perl is following a hard coded path for #INC.This kind of behaviour is observed only on Linux.
I am worried for I cannot roll to production for there are scripts that have been running for older version and if this kind of behaviour exists I would need to know if its possible to fix or this is a known behaviour of Linux.
I am not sure could this be because now the older links after upgrade is been pointed to newer version and just linking is not sufficient and need to modify something more on LINUX?
Note:
1.The perl modules are seperately maintained for each version
2.I am not mixing any of the files with previous version.
3. We want all of the old perl scripts running in production servers not to break and use latest version instead for the mainatainence of Perl versions.
3a.Hence a need to tweak the links pointing to latest version instead of their own versions.
Observation:
Only on Linux seeing this behaviour.
One point worth noting is when i twek links of older version to latest version. the #INC automatically is updated for latest version INC and not in LINUX.
Am i missing something here?
I've never seen this problem on Linux. I leave the original perl in its location (/usr/bin/perl), and simply compile my own perl to install to /usr/local/bin (or whatever), and have never seen any breakage of the old version.
You don't say
how you came to have a /usr/standard_perl/perl588 (compiled, given in rpm format or something, pre-compiled tarball, ...)
what options you used when configuring the compilation
You're also very vague with your details - perl58_link, standard_perl, etc. - where is this really? Most of the time it doesn't matter, but sometimes it does.
If you move the link back, do things start to work? If you move the entire 5.8.8 tree somewhere else, do things start to work? Can you recover your base perl from RPM or whatever to try to make it work? IMO, the base perl working is paramount, a secondary perl is always bonus. (I'd take the same opinion of other core unix tools, like shells, awk, sed, or even python or whatever your distro uses for package management. Less so for non-core tools like Java, but if I were running Java apps in production then I'd say the same here, too.)
Leave the system perl executable alone, compile your own, and have your Perl programs run using the one you compiled
All system programs written in Perl should start with:
#! /usr/bin/perl
All non-system Perl programs, user written programs:
This one will use which ever perl executable is found first on $PATH. (same as 'which perl')
#! /usr/bin/env perl
Another option is to specify exactly where the executable you want to use is:
#! /opt/bin/perl
#! /opt/perl/bin/perl
#! /opt/perl/5.10.0/bin/perl
#! /opt/perl-5.10.0/bin/perl
#! /home/$user/perl/bin/perl
#! ~/bin/perl
Or what ever the path to the perl executable is.
Never replace /usr/bin/perl with one you compiled yourself!
I did this once on Ubuntu 7.10, and it broke my system. I could login, and do most everything, but I couldn't change the appearance, for example. I ended up running 'sudo nano $filename' on every Perl program on my computer, and change them so they would run under Perl 5.10, instead of Perl 5.8.
After which I had to install Ubuntu 8.10 from scratch, when it finally came out.
You could also experience incompatibilities if you use cpan or cpanp to install modules, because they could have an incompatible feature change. And for a non-binary compatible perl executable, you have to reinstall all modules that require XSubs.
Thats why all Perl programs that I write I add the header '#!/usr/bin/env perl', and add the path to the Perl executable, to the beginning of the $PATH variable.

Resources