tsx-11.mit.edu
in
/pub/linux/docs/linux-standards/fsstnd/
. Specific
questions about following the standard may be asked on
debian-devel, or referred to Daniel Quinlan, the FSSTND
coordinator, at quinlan@pathname.com.
/usr/local
, either by putting them in the filesystem archive to
be unpacked by dpkg or by manipulating them in their maintainer
scripts.
However, the package should create empty directories below
/usr/local
so that the system administrator knows where to
place site-specific files. These directories should be removed on
package removal if they are empty.
Note, that this applies only to directories below
/usr/local
, not in /usr/local
. The directory
/usr/local
itself may only contain the sub-directories listed
in FSSTND, section 4.8. However, you may create directories below them
as you wish. You may not remove any of the directories listed in 4.8,
even if you created them.
Since /usr/local
may be mounted read-only from a remote server,
these directories have to be created and removed by the postinst
and prerm
maintainer scripts. These scripts must not fail if
either of these operations fail. (In the future, it will be possible to
tell dpkg not to unpack files matching certain patterns, so
that the directories can be included in the .deb
packages and
system administrators who do not wish these directories in /usr/local
do not need to have them.)
For example, the emacs package will contain
mkdir -p /usr/local/lib/emacs/site-lisp || truein the
postinst
script, and
rmdir /usr/local/lib/emacs/site-lisp && \ rmdir /usr/local/lib/emacs || \ truein the
prerm
script.
If you do create a directory in /usr/local
for local additions
to a package, you must ensure that settings in /usr/local
take precedence over the equivalents in /usr
.
The /usr/local
directory itself and all the subdirectories
created by the package should have permissions 2775 (group-writable
and set-group-id) and be owned by root.staff
.
Some user ids (UIDs) and group ids (GIDs) are reserved globally for use by certain packages. Because some packages need to include files which are owned by these users or groups, or need the ids compiled into binaries, these ids must be used on any Debian system only for the purpose for which they are allocated. This is a serious restriction, and we should avoid getting in the way of local administration policies. In particular, many sites allocate users and/or local system groups starting at 100.
Apart from this we should have dynamically allocated ids, which should by default be arranged in some sensible order--but the behaviour should be configurable.
No package except base-passwd
may modify /etc/passwd
,
/etc/shadow
, or /etc/group
.
The UID and GID ranges are as follows:
passwd
and
group
files of all Debian systems, new ids in this range being added
automatically as the base-passwd
package is updated.
Packages which need a single statically allocated uid or gid should
use one of these; their maintainers should ask the base-passwd
maintainer for ids.
adduser
--system
' to create the group and/or user. adduser will
check for the
existence of the user or group, and if necessary choose an unused id
based on the ranged specified in adduser.conf
.
adduser.conf
may be used to modify this behaviour.
These ids are for packages which are obscure or which require many
statically-allocated ids. These packages should check for and create
the accounts in /etc/passwd
or /etc/group
(using
adduser if it has this facility) if necessary. Packages
which are likely to require further allocations should have a `hole'
left after them in the allocation, to give them room to grow.
nobody
.'
(uid_t)(-1) == (gid_t)(-1)
. NOT TO BE USED, because it is the
error return sentinel value.
Generally the following compilation parameters should be used:
CC = gcc CFLAGS = -O2 -g -Wall # sane warning options vary between programs LDFLAGS = # none install -s # (or use strip on the files in debian/tmp)
Note that all installed binaries should be
stripped, either by using the -s
flag to install, or by calling
strip on the binaries after they have been copied into
debian/tmp
but before the tree is made into a package.
The -g
flag is useful on compilation so that you have available a
full set of debugging symbols in your built source tree, in case
anyone should file a bug report involving (for example) a core dump.
The -N
flag should not be used. On a.out systems it may have
been useful for some very small binaries, but for ELF it has no good
effect.
It is up to the package maintainer to decide what compilation options
are best for the package. Certain binaries (such as
computationally-intensive programs) may function better with certain
flags (-O3
, for example); feel free to use them. Please use good
judgment here. Don't use flags for the sake of it; only use them if
there is good reason to do so. Feel free to override the upstream
author's ideas about which compilation options are best--they are
often inappropriate for our environment.
-fPIC
, and the static version must not be. In other words, each
*.c
file is compiled twice.
You have to specify the gcc option -D_REENTRANT
when building
a library (either static or shared) to make the library compatible with
LinuxThreads.
Note that all installed shared libraries should be stripped with
strip --strip-unneeded <your-lib>(The option `--strip-unneeded' makes
strip
remove only the symbols
which aren't needed for relocation processing.)
Shared libraries can function perfectly well when
stripped, since the symbols for dynamic linking are in a separate part
of the ELF object file.Note that under some circumstances it may be useful to install a shared library unstripped, for example when building a separate package to support debugging.
Please make sure that you use only released versions of shared libraries to build your packages; otherwise other users will not be able to run your binaries properly. Producing source packages that depend on unreleased compilers is also usually a bad idea.
For a straightforward library which has a development environment and
a runtime kit including just shared libraries you need to create two
packages: libraryname
soname
(soname is
the shared object name of the shared library--it's the thing that has
to match exactly between building an executable and running it for the
dynamic linker to be able run the program; usually the soname
is the major number of the library) and
libraryname
soname
-dev
.
If you prefer only to support one development version at a time you
may name the development package libraryname
-dev
; otherwise
you may wish to use dpkg's conflicts mechanism to ensure that
the user only installs one development version at a time (after all,
different development versions are likely to have the same header
files in them, causing a filename clash if both are installed).
Typically the development version will also need an exact version
dependency on the runtime library, to make sure that compilation and
linking happens correctly.
Packages which use the shared library should have a dependency on the
name of the shared library package,
libraryname
soname
. When the soname changes you
can have both versions of the library installed while moving from the
old library to the new.
If your package has some run-time support programs which use the
shared library you must not put them in the shared library
package. If you do that then you won't be able to install several
versions of the shared library without getting filename clashes.
Instead, either create a third package for the runtime binaries (this
package might typically be named libraryname
-runtime
--note
the absence of the soname in the package name) or if the
development package is small include them in there.
If you have several shared libraries built from the same source tree you can lump them all together into a single shared library package, provided that you change all their sonames at once (so that you don't get filename clashes if you try to install different versions of the combined shared libraries package).
Follow the directions in the Debian Packaging Manual for
putting the shared library in its package, and make sure you include a
shlibs
control area file with details of the dependencies for
packages which use the library.
Shared libraries should not be installed executable, since ld.so does not require this and trying to execute a shared library results in a core dump.
#!
line naming
the shell to be used to interpret them.
In the case of Perl scripts this should be #!/usr/bin/perl
.
Shell scripts (sh and bash) should almost certainly
start with set -e
so that errors are detected. Every script
must use set -e
or check the exit status of every
command.
The standard shell interpreter `/bin/sh
' may be a symbolic
link to any POSIX compatible shell. Thus, shell scripts specifying
`/bin/sh
' as interpreter may only use POSIX features. If a
script requires non-POSIX features from the shell interpreter, the
appropriate shell has to be specified in the first line of the script
(e.g., `#!/bin/bash
') and the package has to depend on the
package providing the shell (unless the shell package is marked
`Essential', e.g., in the case of bash).
Restrict your script to POSIX features when possible so that it may
use /bin/sh
as its interpreter. If your script works with
ash, it's probably POSIX compliant, but if you are in doubt,
use /bin/bash
.
Perl scripts should check for errors when making any system calls,
including open
, print
, close
, rename
and
system
.
csh and tcsh should be avoided as scripting languages.
See Csh Programming Considered Harmful, one of the
comp.unix.*
FAQs. It can be found on rtfm.mit.edu
in
/pub/usenet-by-group/comp.unix.programmer/Csh_Programming_Considered_Harmful
.
If an upstream package comes with csh scripts then you must
make sure that they start with #!/bin/csh
and make your
package depend on the c-shell virtual package.
Any scripts which create files in world-writable directories (e.g., in
/tmp
) have to use a mechanism which will fail if a file with
the same name already exists.
The Debian base distribution provides the tempfile and mktemp utilities for use by scripts for this purpose.
In addition, symbolic links should be specified as short as possible, i.e., link targets like `foo/../bar' are depreciated.
Note that when creating a relative link using ln it is not necessary for the target of the link to exist relative to the working directory you're running ln from; nor is it necessary to change directory to the directory where the link is to be made. Simply include the string that should appear as the target of the link (this will be a pathname relative to the directory in which the link resides) as the first argument to ln.
For example, in your Makefile or debian/rules
, do things
like:
ln -fs gcc $(prefix)/bin/cc ln -fs gcc debian/tmp/usr/bin/cc ln -fs ../sbin/sendmail $(prefix)/bin/runq ln -fs ../sbin/sendmail debian/tmp/usr/bin/runq
A symbolic link pointing to a compressed file should always have the
same file extension as the referenced file. (For example, if a file
`foo.gz
' is referenced by a symbolic link, the filename of
the link has to end with `.gz
' too, as in `bar.gz.')
If a package needs any special device files that are not included in
the base system, it has to call makedev in the postinst
script, after asking the user for permission to do so.
No package should remove any device files in the postrm
or any
other script. This is left to the system administrator.
Debian uses the serial devices /dev/tty*
. Programs using the
old /dev/cu*
devices should be changed to use
/dev/tty*
.
/etc
. If there are several you should consider creating a
subdirectory named after your package.
It is almost certain that any file in /etc
that is in your
package's filesystem archive should be listed in dpkg's
conffiles
control area file. (See the Debian Packaging
Manual).
Only packages that are tagged conflicting with each other may
specify the same file as conffile
. A package may not modify a
configuration file of another package.
If two or more packages use the same configuration file, one of these
packages has to be defined as owner of the configuration file,
i.e., it has to list the file as conffile
and has to provide
a program that modifies the configuration file.
The other packages have to depend on the owner package and use that program to update the configuration file.
Sometimes it's appropriate to build a new package, which just provides the basic infrastructure for the other packages and which manages the shared configuration files. (Check out the sgml-base package as an example.)
Files in /etc/skel
will automatically be copied into new user
accounts by adduser. They should not be referenced there by
any program.
Therefore, if a program needs a dotfile to exist in advance in
$HOME
to work sensibly that dotfile should be installed in
/etc/skel
(and listed in conffiles, if it is not generated and
modified dynamically by the package's installation scripts).
However, programs that require dotfiles in order to operate sensibly (dotfiles that they do not create themselves automatically, that is) are a bad thing, and programs should be configured by the Debian default installation as close to normal as possible.
Therefore, if a program in a Debian package needs to be configured in
some way in order to operate sensibly that configuration should be
done in a site-wide global configuration file elsewhere in
/etc
. Only if the program doesn't support a site-wide default
configuration and the package maintainer doesn't have time to add it
should a default per-user file be placed in /etc/skel
.
/etc/skel
should be as empty as we can make it. This is
particularly true because there is no easy mechanism for ensuring that
the appropriate dotfiles are copied into the accounts of existing
users when a package is installed.
Ideally the sysadmin should not have to do any configuration other
than that done (semi-)automatically by the postinst
script.
Files should be owned by root.root
, and made writable only by
the owner and universally readable (and executable, if appropriate).
Directories should be mode 755 or (for group-writability) mode 2775. The ownership of the directory should be consistent with its mode--if a directory is mode 2775, it should be owned by the group that needs write access to it.
Setuid and setgid executables should be mode 4755 or 2755 respectively, and owned by the appropriate user or group. They should not be made unreadable (modes like 4711 or 2711 or even 4111); doing so achieves no extra security, because anyone can find the binary in the freely available Debian package--it is merely inconvenient. For the same reason you should not restrict read or execute permissions on non-set-id executables.
Some setuid programs need to be restricted to particular sets of users, using file permissions. In this case they should be owned by the uid to which they are set-id, and by the group which should be allowed to execute them. They should have mode 4754; there is no point in making them unreadable to those users who must not be allowed to execute them.
Do not arrange that the system administrator can only reconfigure the package to correspond to their local security policy by changing the permissions on a binary. Ordinary files installed by dpkg (as opposed to conffiles and other similar objects) have their permissions reset to the distributed permissions when the package is reinstalled. Instead you should consider (for example) creating a group for people allowed to use the program(s) and making any setuid executables executable only by that group.
If you need to create a new user or group for your package there are two possibilities. Firstly, you may need to make some files in the binary package be owned by this user or group, or you may need to compile the user or group id (rather than just the name) into the binary (though this latter should be avoided if possible). In this case you need a statically allocated id.
You must ask for a user or group id from the base system maintainer,
and must not release the package until you have been allocated one.
Once you have been allocated one you must make the package depend on a
version of the base system with the id present in /etc/passwd
or /etc/group
, or alternatively arrange for your package to
create the user or group itself with the correct id (using
adduser
) in its pre- or post-installation script (the latter is
to be preferred if it is possible).
On the other hand, the program may able to determine the uid or gid from the group name at runtime, so that a dynamic id can be used. In this case you must choose an appropriate user or group name, discussing this on debian-devel and checking with the base system maintainer that it is unique and that they do not wish you to use a statically allocated id instead. When this has been checked you must arrange for your package to create the user or group if necessary using adduser in the pre- or post-installation script (again, the latter is to be preferred if it is possible).
Note that changing the numeric value of an id associated with a name is very difficult, and involves searching the filesystem for all appropriate files. You need to think carefully whether a static or dynamic id is required, since changing your mind later will cause problems.
/etc/init.d
directory contains the scripts executed by
init at boot time and when init state (or `runlevel') is
changed (see init(8)
).
These scripts are being referenced by symbolic links in the
/etc/rc
n.d
directories. When changing runlevels,
init looks in the directory /etc/rc
n.d
for the
scripts it should execute, where n is the runlevel that is being
changed to, or `S' for the boot-up scripts.
The names of the links all have the form S
mmscript
or
K
mmscript
where mm is a two-digit number and
script is the name of the script (this should be the same as the
name of the actual script in
/etc/init.d
.
When init changes runlevel first the targets of the links whose
names starting with a K
are executed, each with the single
argument stop
, followed by the scripts prefixed with an S
,
each with the single argument start
. The K
links are
responsible for killing services and the S
link for starting
services upon entering the runlevel.
For example, if we are changing from runlevel 2 to runlevel 3, init
will first execute all of the K
prefixed scripts it finds in
/etc/rc3.d
, and then all of the S
prefixed scripts. The
links starting with K
will cause the referred-to file to be
executed with an argument of stop
, and the S
links with an
argument of start
.
The two-digit number mm is used to decide which order to start
and stop things in--low-numbered links have their scripts run first.
For example, the K20
scripts will be executed before the K30
scripts. This is used when a certain service must be started before
another. For example, the name server bind might need to be
started before the news server inn so that inn can set
up its access lists. In this case, the script that starts bind
should have a lower number than the script that starts inn so
that it runs first:
/etc/rc2.d/S17bind /etc/rc2.d/S70inn
/etc/init.d
to start
or stop services at boot time or during a change of runlevel. These
scripts should be named /etc/init.d/
package
, and they
should accept one argument, saying what to do:
start
stop
restart
reload
force-reload
start
, stop
, restart
, and force-reload
options
must be supported by all scripts in /etc/init.d
, the
reload
option is optional.
The init.d
scripts should ensure that they will behave sensibly
if invoked with start
when the service is already running, or
with stop
when it isn't, and that they don't kill
unfortunately-named user processes. The best way to achieve this is
usually to use start-stop-daemon.
If a service reloads its configuration automatically (as in the case
of cron, for example), the reload
option of the
init.d
script should behave as if the configuration has been
reloaded successfully.
These scripts should not fail obscurely when the configuration files
remain but the package has been removed, as the default in dpkg
is to leave configuration files on the system after the package has
been removed. Only when it is executed with the --purge
option
will dpkg remove configuration files. Therefore, you should include a
test
statement at the top of the script, like this:
test -f program-executed-later-in-script || exit 0
/etc/rc
n.d
symbolic links from their postinst
and
postrm
scripts.
You should use this script to make changes to /etc/rc
n.d
and never include any /etc/rc
n.d
symbolic links in
the actual archive.
By default update-rc.d will start services in each of the
multi-user state runlevels (2, 3, 4, and 5) and stop them in the halt
runlevel (0), the single-user runlevel (1) and the reboot runlevel
(6). The system administrator will have the opportunity to customize
runlevels by simply adding, moving, or removing the symbolic links in
/etc/rc
n.d
.
To get the default behaviour for your package, put in your
postinst
script
update-rc.d package default >/dev/nulland in your
postrm
if [ purge = "$1" ]; then update-rc.d package remove >/dev/null fi
This will use a default sequence number of 20. If it does not matter
when or in which order the script is run, use this default. If it
does, then you should talk to the maintainer of the sysvinit
package or post to debian-devel
, and they will help you choose
a number.
For more information about using update-rc.d
, please consult its
manpage update-rc.d(8)
.
/etc/rc.boot
, which contains
scripts which are run once per machine boot. This facility is
provided for initialisation of hardware devices, cleaning up of
leftover files, and so forth.For example, the kbd package provides a script here for initialising the keyboard layout and console font and mode.
The files in /etc/rc.boot
should not be links into
/etc/init.d
--they should be the scripts themselves.
rc.boot
should not be used for starting general-purpose
daemons and similar activities. This should be done using the
rc
n.d
scheme, above, so that the services can be started
and stopped cleanly when the runlevel changes or the machine is to be
shut down or rebooted.
/etc/rc
n.d/*
symbolic links in
the .deb
filesystem archive! This will cause problems!
You should create them with update-rc.d, as above.
Do not include the /etc/rc
n.d/*
symbolic links in
dpkg's conffiles list! This will cause problems! Do,
however, include the /etc/init.d
scripts in conffiles. (This
is important since we want to give the local system administrator the
chance to adapt the scripts to the local system--e.g., to disable a
service without deinstalling the package, or to specify some special
command line options when starting a service--while making sure her
changes aren't lost during the next package upgrade.)
/etc/init.d
, naming
the script appropriately bind
. As you can see, the script
interprets the argument reload
to send the nameserver a HUP
signal (causing it to reload its configuration); this way the user can
say /etc/init.d/bind reload
to reload the name server.
#!/bin/sh # # Original version by Robert Leslie <rob@mars.org>, edited by iwj and cs test -x /usr/sbin/named || exit 0 case "$1" in start) echo -n "Starting domain name service: named" start-stop-daemon --start --quiet --exec /usr/sbin/named echo "." ;; stop) echo -n "Stopping domain name service: named" start-stop-daemon --stop --quiet \ --pidfile /var/run/named.pid --exec /usr/sbin/named echo "." ;; restart) echo -n "Restarting domain name service: named" start-stop-daemon --stop --quiet \ --pidfile /var/run/named.pid --exec /usr/sbin/named start-stop-daemon --start --verbose --exec /usr/sbin/named echo "." ;; force-reload|reload) echo -n "Reloading configuration of domain name service: named" start-stop-daemon --stop --signal 1 --quiet \ --pidfile /var/run/named.pid --exec /usr/sbin/named echo "." ;; *) echo "Usage: /etc/init.d/bind {start|stop|restart|reload|force-reload}" >&2 exit 1 ;; esac exit 0
Another example on which to base your /etc/init.d
scripts is in
/etc/init.d/skeleton
.
If this package is happy with the default setup from
update-rc.d, namely an ordering number of 20 and having named
running in all runlevels, it can say in its postinst
:
update-rc.d bind default >/dev/nullAnd in its
postrm
, to remove the links when the package is purged:
if [ purge = "$1" ]; then update-rc.d acct remove >/dev/null fi
/etc/crontab
, nor
may they modify the files in /var/spool/cron/crontabs
.If a package wants to install a job that has to be executed via cron, it should place a file with the name if the package in one of the following directories:
/etc/cron.daily /etc/cron.weekly /etc/cron.monthlyAs these directory names say, the files within them are executed on a daily, weekly, or monthly basis, respectively.
If a certain job has to be executed more frequently than `daily,' the
package should install a file
/etc/cron.d/<package-name>
tagged as configuration
file. This file uses the same syntax as /etc/crontab
and is
processed by cron automatically. (Note, that scripts in the
/etc/cron.d
directory are not handled by
anacron. Thus, you should only use this directory for jobs
which may be skipped if the system is not running.)
All files installed in any of these directories have to be scripts (shell scripts, Perl scripts, etc.) so that they can easily be modified by the local system administrator. In addition, they have to be registered as configuration file.
The scripts in these directories have to check, if all necessary programs are installed before they try to execute them. Otherwise, problems will arise when a package was removed (but not purged), since the configuration files are kept on the system in this situation.
/etc/init.d
scripts. The intent is to
improve the consistency of Debian's startup and shutdown look and
feel.Please look very careful at the details. We want to get the messages to look exactly the same way concerning spaces, punctuation, and case of letters.
Here is a list of overall rules that you should use when you create output messages. They can be useful if you have a non-standard message that isn't covered in the sections below.
I'm starting network daemons: nfsd mountd.just say
Starting network daemons: nfsd mountd.
The following formats must be used
Use this format if your script starts one or more daemons. The output should look like this (a single line, no leading spaces):
Starting <description>: <daemon-1> <daemon-2> <...> <daemon-n>.The <description> should describe the subsystem the daemon or set of daemons are part of, while <daemon-1> up to <daemon-n> denote each daemon's name (typically the file name of the program).
For example, the output of /etc/init.d/lpd would look like:
Starting printer spooler: lpd.
This can be achieved by saying
echo -n "Starting printer spooler: lpd" start-stop-daemon --start --quiet lpd echo "."in the script. If you have more than one daemon to start, you should do the following:
echo -n "Starting remote filesystem services:" echo -n " nfsd"; start-stop-daemon --start --quiet nfsd echo -n " mountd"; start-stop-daemon --start --quiet mountd echo -n " ugidd"; start-stop-daemon --start --quiet ugidd echo "."This makes it possible for the user to see what takes so long and when the final daemon has been started. Please be careful where to put spaces: In the example above the system administrator can easily comment out a line if he don't wants to start a specific daemon, while the displayed message still looks good.
If you have to set up different parameters of the system upon boot up, you can use this format:
Setting <parameter> to `<value>'.
You can use the following echo statement to get the quotes right:
echo "Setting DNS domainname to \`"value"'."
Note that the left quotation mark (`) is different from the right (').
When you stop a daemon you should issue a message similar to the startup message, except that `Starting' is replaced with `Stopping'.
So stopping the printer daemon will like like this:
Stopping printer spooler: lpd.
There a several examples where you have to run a program at system startup or shutdown to perform a specific task. For example, setting the system's clock via `netdate' or killing all processes when the system comes down. Your message should like this:
Doing something very useful...done.You should print the `done.' right after the job has been completed, so that the user gets informed why he has to wait. You can get this behaviour by saying
echo -n "Doing something very useful..." do_something echo "done."in your script.
When a daemon is forced to reload its configuration files you should use the following format:
Reloading <daemon's-name> configuration...done.
If you have to print a message that doesn't fit into the styles described above, you can use something appropriate, but please have a look at the overall rules listed above.
menu
packages provides a unique interface between
packages providing applications and documents, and menu programs
(either X window managers or text-based menu programs as
pdmenu).
All packages that provide applications that need not be passed any
special command line arguments for normal operation should register a
menu entry for those applications, so that users of the menu
package will automatically get menu entries in their window managers,
as well in shells like pdmenu
.
Please refer to the Debian Menu System document that comes
with the menu
package for information about how to register your
applications and web documents.
Here is a list that contains certain keys and their interpretation:
<--
Delete
Control+H
The following list explains how the different programs should be set up to achieve this:
<--
' generates KB_Backspace in X.
Delete
' generates KB_Delete in X.
ESC [ 3 ~
(this is the vt220 escape
code for the `delete character' key). This must be done by loading
the resources using xrdb on all local X displays, not using the
application defaults, so that the translation resources used
correspond to the xmodmap settings.
<--
' generate DEL, and
`Delete' generate ESC [ 3 ~
(this is the case at the moment).
^?
.
ESC [ 3 ~
for kdch1, just
like TERM=linux and TERM=vt220.
^H
to help as always.
This will solve the problem except for:
<--
key that cannot be made to produce
anything except ^H
. On these terminals Emacs help will be
unavailable on ^H
(assuming that the `stty erase' character takes
precedence in Emacs, and has been set correctly). M-x help or F1
(if available) can be used instead.
^H
for stty erase. However, modern
telnet versions and all rlogin versions propagate stty settings,
and almost all UNIX versions honour stty erase. Where the stty
settings are not propagated correctly things can be made to work by
using stty manually.
<--
and Delete to generate KB_Delete). We can
change the behaviour of their X clients via the same X resources
that we use to do it for our own, or have our clients be configured
via their resources when things are the other way around. On
displays configured like this Delete will not work, but <--
will.
<--
will.
If a program should depend on environment variables for its configuration, the program has to be changed to fall back to a reasonable default configuration if these environment variables are not present. If this cannot be done easily (e.g., if the source code of a non-free program is not available), the program should be replaced by a small `wrapper' shell script which sets the environment variables and calls the original program.
Here is an example of a wrapper script for this purpose:
#!/bin/sh BAR=/var/lib/fubar export BAR exec /usr/lib/foo/foo "$@"
Furthermore, as /etc/profile
is a configuration file of the
bash package, no other package may put any environment
variables or other commands into that file.