Package Management and Service Control on Linux, BSD, and Solaris

A Phrase Book for RPM/yum/urpmi, apt-get/dpkg, pkg*, and pkg_*

Red Hat invented the RPM (Red Hat Package Manager) package management system. It includes databases in /var/lib/rpm/* and the rpm command-line interface. RPM is used on many Linux distributions. Put simply (and therefore a little inaccurately), pretty much all Linux distributions use rpm for package management, except for Debian and its derivatives like Ubuntu, plus Slackware, where tar and very careful note-taking remain supreme.

The two commands yum (found on most RPM-based distributions) and urpmi (found on Mandriva) are high-level wrappers around rpm, giving it the same automation and ease of use found with Debian's apt-get. If you don't use either yum or urpmi then for installation or upgrade you must have the desired package and all its dependencies on the local system, and getting the dependencies straighted out can take long enough that you finally install the now huge list of packages only to realize you forgot what you were trying to do in the first place.

Debian and Ubuntu use the dpkg and apt-get commands to manage packages.

I have also included the OpenBSD package management tools pkg_add, pkg_info, and pkg_delete here. The pkg_add command does it own dependency management.

With pkg_add you can do both installation and upgrading. The package to be added can be specified as a path to a local file or as a URL. If the files are not in the current working directory, the environment variable PKG_PATH is used to search for them. And yes, PKG_PATH could be set to the URL of an FTP or HTTP server directory containing OpenBSD packages. Here is how to update all installed packages from the master FTP site with two commands:

# setenv PKG_PATH ftp://ftp.openbsd.org/pub/OpenBSD/`uname -r`/packages/i386
# pkg_add -u -D update

Most recently, I added the Solaris package management tools pkgadd, pkginfo, pkgchk, and pkgrm.

Below is a "phrase book" listing package management actions and how to do them in all of the command sets.

Commands for Package Management

For the Linux rpm commands and the Solaris pkgadd commands, the package file must be on the local system.

For the Linux yum, urpmi, and apt-get commands, the package file is downloaded from a network repository.

For the OpenBSD pkg_add commands, the package file can be on the local system or downloaded from a network repository, as described above.

Install package foo

Linux RPM
rpm -Uvh foo-1.2.3.i386.rpm
yum install foo
urpmi foo
Linux apt-get/dpkg
apt-get install foo
OpenBSD pkg_add
pkg_add foo-1.2.3.tgz
Or, using "stems", just name the package and the tool will look for that name plus -version.tgz
pkg_add foo
Solaris pkgadd
pkgadd -d ./foo-1.2.3.gz
Or, if the package file is stored in the standard directory of /var/spool/pkg/
pkgadd foo-1.2.3.gz

Upgrade package foo when an earlier version is already installed

Linux RPM
rpm -Uvh foo-1.2.3.i386.rpm
yum upgrade foo
urpmi foo
Linux apt-get/dpkg There doesn't seem to be a clean way of doing this, and if I correctly understand, this is intentional. Debian intentionally does a great deal of testing compared to other Linux distributions, and you should follow their directions. That means performing all available upgrades at any time, not just an upgrade to one package.

This suggests that you should check for and apply all available updates as shown below before installing a new package:
apt-get update
apt-get upgrade
apt-get install foo 
OpenBSD pkg_add
pkg_add -u foo-1.2.3.tgz
Or, using "stems":
pkg_add -u foo
Solaris This is done with patchadd as there should be a patch. If there is not a patch, remove the current version with pkgrm and then add the new one with pkgadd.

Check to see which packages have upgrades available

Linux RPM
yum check-update
urpmi.update -a
Linux apt-get/dpkg
apt-get update
OpenBSD pkg_add
pkg_add -u -n
Solaris See if you have mail from Oracle...

Update all packages with available upgrades

Linux RPM
yum upgrade
urpmi --auto-select
Linux apt-get/dpkg
apt-get upgrade
OpenBSD pkg_add
pkg_add -u
In theory, that will be enough. But some package updates will probably fail when you are updating from one release to the next. So, tell it to waive the failsafes and run scripts that might fail:
pkg_add -u -D update
Solaris Again, this is not really automated. You can put a list of patches into a file and then do something like this:
patchadd -M /var/sadm/spool patchlist

Remove the installed package bar

Linux RPM
rpm --erase bar
Linux apt-get/dpkg
apt-get remove bar
OpenBSD pkg_add
pkg_delete bar
Solaris pkgrm
pkgrm bar

List all packages currently installed on the system

Linux RPM
rpm -qa
Linux apt-get/dpkg
dpkg -l
OpenBSD pkg_info
pkg_info
Solaris pkginfo
pkginfo

Display the information about the installed package foo

Linux RPM
rpm -qi foo
Linux apt-get/dpkg
dpkg -s foo
OpenBSD pkg_info
pkg_info foo
Solaris pkginfo
pkginfo -l foo

List the files belonging to the installed package foo

Linux RPM
rpm -ql foo
Linux apt-get/dpkg
dpkg --listfiles foo
OpenBSD pkg_info
pkg_info -L foo
Solaris
grep foo /var/sadm/install/contents
The second field of each lines specifies the file type:
f  file
s  symbolic link in form link=file
d  directory

Which package owns the file /etc/foo.conf?

Linux RPM
rpm -qf /etc/foo.conf
Linux apt-get/dpkg
dpkg -S /etc/foo.conf
OpenBSD pkg_info
pkg_info -E /etc/foo.conf
Solaris
pkgchk -l -p /etc/foo.conf
Or, more simply:
grep /etc/foo.conf /var/sadm/install/contents
The second field of each lines specifies the file type:
f  file
s  symbolic link in form link=file
d  directory

Which package could I add to get the file /etc/foo.conf?

Linux RPM
yum provides /etc/foo.conf
urpmf /etc/foo.conf
Linux apt-get/dpkg
dpkg-query -S /etc/foo.conf
apt-file search /etc/foo.conf
OpenBSD pkg_info There doesn't seem to be an easy way of doing this. A simple shell script run in a directory where all package files have been downloaded could accomplish it.
Solaris There doesn't seem to be an easy way of doing this.

Which other packages does the foo package require?

Linux RPM
rpm -qR foo
Linux apt-get/dpkg
apt-cache depends foo
OpenBSD pkg_info There doesn't seem to be an easy way of doing this.
Solaris For at least a partial list:
patchadd -p | grep foo 

Verify all installed packages, reporting files that have been removed, changed, or had ownership or permission changed

Linux RPM
rpm -a --verify
Linux apt-get/dpkg
debsums
OpenBSD pkg_check
pkg_check
Solaris
pkginfo | awk '{print $2}' | xargs pkgchk

For even more tricks, see this Ubuntu page.

How to Build Binary Packages From Source

Read the flowchart from top to bottom, where we assume you're building a package named newpackage:

What you must accomplish Linux RPM system Linux apt-get/dpkg system
Install any dependencies — packages that must be installed before the binary can be built You can't easily do this in advance when building from source RPM on an RPM-based system. Continue with the following steps, when you need something you'll be told and you can install it with:
yum install needed
sudo apt-get build-dep newpackage
Install the source code.
yum install newpackage.src
cd /usr/src/distro/SRPMS
rpm -Uvh newpackage-version.src.rpm
Alternatively, download the SRPM file with FTP or a browser.

You're going to have to figure out what to use in place of distro — it might really be something like your distribution's name, like redhat, or it might be rpms, or whatever. If you really can't figure it out, get a hint from this:
ls -ld /usr/src/*/RPMS
cd /path/to/your/build/area
apt-get source newpackage
Yes, this can be done anywhere. Following steps are relative to wherever you went in this step.
Examine and possibly modify the build specification — compilation options, embedded package information, change log, etc.
cd /usr/src/distro/SPECS
vi newpackage.spec
cd newpackage-release
vi debian/rules debian/changelog
debchange
Build the binary package.
rpmbuild -bb newpackage.spec
dpkg-buildpackage -uc -b
-uc for an unsigned .changes,
-b to build a binary
Did the build go well? If so, clean up.
ls /usr/src/distro/RPMS/*
rpmbuild --clean newpackage.spec
You should see the newly built RPM file in one of those architecture-specific subdirectories.
ls ../*deb
./debian/rules clean
Install the binary package.
cd /usr/src/distro/RPMS/arch
rpm -Uvh newpackage-version.arch.rpm
Replace arch with the architecture subdirectory you spotted in the previous step.
cd ..
sudo dpkg -i newpackage*deb

Commands to Control Services

Solaris is now completely different from other implementations of UNIX. You check for the list of running services with the svcs command:

# svcs
# svcs | grep network

Control services with the svcadm command, It starts or stops that service right now, while also configuring it to be automatically started or not in the future.

# svcs | grep network
# svcadm disable network/finger
# svcs | grep network

This isn't an issue on BSD Unix — control of which services to start is done very simply in /etc/rc.conf with lines like this:

rdate_flags=NO    # for normal use: [RFC868-host] or [-n RFC2030-host]
ntpd_flags=NO     # for normal use: ""
httpd_flags="-u"  # use "-DSSL" after reading ssl(8), and/or "-u" to disable chroot 

Most Linux distributions, however, are based on the relatively complicated SVR4 organization.

To start or stop a service on any Linux, use its boot script directly. The distributions include specialized wrapper scripts that don't seem to accomplish anything beyond confusing people about how to do this, and locking users into the one distribution they have managed to figure out. Just use the boot script directly with parameters status, stop, start, and restart.

# /etc/init.d/httpd status
httpd is stopped
# /etc/init.d/httpd start
OK
# /etc/init.d/httpd status
httpd is running 

SVR4 Unix generally specifies that there should be a collection of directories, one per defined run level, containing links to the services that should be stopped or started in that run level.

Those directories specifying run levels are generally /etc/rc[0-6].d/ or possibly /etc/rc.d/rc[0-6].d/.

The kernel starts /sbin/init, which traditionally reads its configuration from the file /etc/inittab. However, the Upstart version of init on Debian and Ubuntu reads the collection of files in the directory /etc/event.d. Basically, each Upstart file in /etc/event.d plays the role of one line from the traditional /etc/inittab.

The following shows how to add or remove services from specified run levels — to specify just which services should run in which run levels. The real effect of running these commands is the creation and deletion of symbolic links in /etc/rc[0-6].d/ pointing to the real scripts in /etc/init.d/, with names starting with "K" or "S" to indicate that the service should be killed or started, respectively, followed by two-digit numbers to specify the order of events.

Ubuntu / Debian

See the run levels in which a given service is started:

# sysv-rc-conf --list apache 

Add a service:

# sysv-rc-conf apache on 

Delete a service:

# sysv-rc-conf apache off 

See the manual page for update-rc.d to see how to do this under fine manual control, assuming you really know what you're doing and the creators of your boot scripts didn't. A "simple" example is that you could do this:

# update-rc.d apache start 88 2 3 4 5 . stop 12 0 1 6 . 

Most All Other Linux Distributions

See the run levels in which a given service is started:

# chkconfig --list httpd 

Add a service:

# chkconfig httpd on 

Delete a service:

# chkconfig httpd off 

According to the manual pages, --add and --del are preferred to on and off. However, if you have peculiar boot scripts like those provided with Red Hat, --add may not add a service because the chkconfig comment field specifies no run levels to which it should be added. Why? I don't know, maybe to lock you into using Red Hat's configuration tools instead of simple commands.

Just add and delete them with on and off. That will add them to run levels 2, 3, 4, and 5, but you only use 3 and 5 anyway.

And that leads to....

Linux Run Levels

Run Level Meaning
0 Shut down, turning off power if possible.
1 Single-user mode, root on the console. Can also be referred to as S or even single from the GRUB boot loader. On Debian and Ubuntu, this probably requires you to type your root password, on others it generally does not.
2 Full multi-user, networking started. Text login only.
Debian & Ubuntu: Networkings services started, this is an appropriate default run level for a server.
Others: This is a fairly useless run level, you probably meant "3"...
3 Full multi-user, all networking services started.
Debian & Ubuntu: Graphical login started, this is an appropriate default run level for a workstation.
Others: Text login only, this is an appropriate default run level for a server.
4 Fairly useless....
5 Other than Debian & Ubuntu, this is the appropriate default run level for a workstation. Full multi-user, all networking services started. Graphical login.
6 Shut down for a reboot.

Back to the general Unix page

My page on hardening default installations of Linux and BSD

My general information security page

Click here to inquire about advertising on this or any page on this site.
Home Unix/Linux Networking Cybersecurity Travel Technical Radio Site Map Contact


Use /bin/vi! Manipulate images with ImageMagick! Hosted on OpenBSD
Hosted on Apache This site is viewable with any browser Valid XHTML 1.0! Valid CSS!
© Bob Cromwell Feb 2012. Created with /bin/vi and ImageMagick, hosted on OpenBSD with Apache.    Root password available here, privacy policy here.