|
Home | Switchboard | Unix Administration | Red Hat | TCP/IP Networks | Neoliberalism | Toxic Managers |
(slightly skeptical) Educational society promoting "Back to basics" movement against IT overcomplexity and bastardization of classic Unix |
|
There are two widespread urban myth about init scripts. The first is that scripts on lower runlevels are executed before scripts on higher runlevel. For example if we go to level 5 that means that scripts on level 3 will be executed.
|
This is not true -- each runlevel is completely autonomous and sequence of runlevel is poorly logical. Only scripts belonging to particular runlevel are executed.
On entering particular run-level first all K-scripts (scripts starting with the capital
K or kill-scripts) are executed in sorted order. Then all S-scripts (scripts starting with capital S, or
start scripts), the script that start daemons
that should be present on a particular run-level are executed.
There are two types of scripts in /etc/init.d:
- Scripts Executed Directly by init
- This is the case only during the boot process or if an immediate system shutdown is initiated (power failure or a user pressing Ctrl-Alt-Del).
- Scripts that are sources by directly executed scripts
- functions and networking are most common scripts in this category.
All scripts are located in /etc/init.d. Scripts for changing the runlevel are also found there, but are called through symbolic links from one of the subdirectories (/etc/init.d/rc0.d to /etc/init.d/rc6.d). This is just for clarity reasons and avoids duplicate scripts if they are used in several runlevels. Because every script can be executed as both a start and a stop script, these scripts must understand the parameters start and stop. In addition most script understand the restart, reload, force-reload, and status options. These options are not necessary for correct functioning of the script:
Option Description start Start service. stop Stop service. restart If the service is running, stop it then restart it. If it is not running, start it. reload Reload the configuration without stopping and restarting the service. force-reload Reload the configuration if the service supports this. Otherwise, do the same as if restart had been given. status Show current status of service. Links in each runlevel-specific subdirectory make it possible to associate scripts with different runlevels. When installing or uninstalling packages, such links are added and removed with the help of the program insserv (or using /usr/lib/lsb/install_initd, which is a script calling this program). See the manual page of insserv for details.
Below is a short introduction to the boot and stop scripts launched first or last, respectively, as well as an explanation of the maintaining script.
- boot
- Executed while starting the system directly using init. It is independent of the chosen runlevel and is only executed once. Here, the proc and pts file systems are mounted and blogd (boot logging daemon) is activated. If the system is booted for the first time after an update or an installation, the initial system configuration is started.
The blogd daemon is a service started by boot and by rc before any other one. It is stopped after the actions triggered by the above scripts (running a number of subscripts, for example) are completed. blogd writes any screen output to the log file /var/log/boot.msg, but only if and when /var is mounted read-write. Otherwise, blogd buffers all screen data until /var becomes available. Get further information about blogd with man blogd.
The script boot is also responsible for starting all the scripts in /etc/init.d/boot.d with a name that starts with S. There, the file systems are checked and loop devices are configured if needed. The system time is also set. If an error occurs while automatically checking and repairing the file system, the system administrator can intervene after first entering the root password. Last executed is the script boot.local.
- boot.local
- Here, enter additional commands to execute at boot before changing into a runlevel. It can be compared to AUTOEXEC.BAT on DOS systems.
- boot.setup
- This script is executed when changing from single user mode to any other runlevel and is responsible for a number of basic settings, such the keyboard layout and initialization of the virtual consoles.
- halt
- This script is only executed while changing into runlevel 0 or 6. Here, it is executed either as halt or as reboot. Whether the system shuts down or reboots depends on how halt is called.
- rc
- This script calls the appropriate stop scripts of the current runlevel and the start scripts of the newly selected runlevel.
You can create your own scripts and easily integrate them into the scheme described above. For instructions about formatting, naming, and organizing custom scripts, refer to the specifications of the LSB and to the man pages of init, init.d, and insserv. Additionally consult the man pages of startproc and killproc.
Creating Your Own init Scripts | |
---|---|
Faulty init scripts may freeze your machine. Edit such scripts with great care and, if possible, subject them to heavy testing in the multiuser environment. Some useful information about init scripts can be found in 10.3. “Runlevels”. |
To create a custom init script for a given program or service, use the file /etc/init.d/skeleton as a template. Save a copy of this file under the new name and edit the relevant program and file names, paths, and other details as needed. You may also need to enhance the script with your own parts, so the correct actions are triggered by the init procedure.
The INIT INFO block at the top is a required part of the script and should be edited. See Example 10.1. “A Minimal INIT INFO Block”.
Example 10.1. A Minimal INIT INFO Block
### BEGIN INIT INFO # Provides: FOO # Required-Start: $syslog $remote_fs # Required-Stop: $syslog $remote_fs # Default-Start: 3 5 # Default-Stop: 0 1 2 6 # Description: Start FOO to allow XY and provide YZ ### END INIT INFO
In the first line of the INFO block, after Provides:, specify the name of the program or service controlled by this init script. In the Required-Start: and Required-Stop: lines, specify all services that need to be started or stopped, respectively, before the service itself is started or stopped. This information is used later to generate the numbering of script names, as found in the runlevel directories. Under Default-Start: and Default-Stop:, specify the runlevels in which the service should automatically be started or stopped. Finally, under Description:, provide a short description of the service in question.
To create the links from /etc/init.d/ to the corresponding runlevel directories (/etc/init.d/rc?.d/), enter the command insserv <new-script-name>. The insserv program evaluates the INIT INFO header to create the necessary links for start and stop scripts in the runlevel directories (/etc/init.d/rc?.d/). The program also takes care of the correct start and stop order for each runlevel by including the necessary numbers in the names of these links. If you prefer a graphical tool to create such links, use the runlevel editor provided by YaST, as described in 10.6. “The YaST Runlevel Editor”.
If a script already present in /etc/init.d/ should be integrated into the existing runlevel scheme, create the links in the runlevel directories right away with insserv or by enabling the corresponding service in the runlevel editor of YaST. Your changes are applied during the next reboot — the new service will be started automatically.
|
Switchboard | ||||
Latest | |||||
Past week | |||||
Past month |
Gentoo Linux Documentation -- Initscripts
Content:
- Runlevels
- Working with rc-update
- Configuring Services
- Writing Init Scripts
- Changing the Runlevel Behaviour
4.a. Runlevels
When you boot your system, you will notice lots of text floating by. If you pay close attention, you will notice this text is the same every time you reboot your system. The sequence of all these actions is called the boot sequence and is (more or less) statically defined.
First, your boot loader will load the kernel image you have defined in the boot loader configuration into memory after which it tells the CPU to run the kernel. When the kernel is loaded and run, it initializes all kernel-specific structures and tasks and starts the init process.
This process then makes sure that all filesystems (defined in /etc/fstab) are mounted and ready to be used. Then it executes several scripts located in /etc/init.d, which will start the services you need in order to have a successfully booted system.
Finally, when all scripts are executed, init activates the terminals (in most cases just the virtual consoles which are hidden beneath Alt-F1, Alt-F2, etc.) attaching a special process called agetty to it. This process will then make sure you are able to log on through these terminals by running login.
Now init doesn't just execute the scripts in /etc/init.d randomly. Even more, it doesn't run all scripts in /etc/init.d, only the scripts it is told to execute. It decides which scripts to execute by looking into /etc/runlevels.
First, init runs all scripts from /etc/init.d that have symbolic links inside /etc/runlevels/boot. Usually, it will start the scripts in alphabetical order, but some scripts have dependency information in them, telling the system that another script must be run before they can be started.
When all /etc/runlevels/boot referenced scripts are executed, init continues with running the scripts that have a symbolic link to them in /etc/runlevels/default. Again, it will use the alphabetical order to decide what script to run first, unless a script has dependency information in it, in which case the order is changed to provide a valid start-up sequence.
Of course init doesn't decide all that by itself. It needs a configuration file that specifies what actions need to be taken. This configuration file is /etc/inittab.
If you remember the boot sequence we have just described, you will remember that init's first action is to mount all filesystems. This is defined in the following line from /etc/inittab:
Code Listing 1.1: The system initialisation line in /etc/inittab si::sysinit:/sbin/rc sysinitThis line tells init that it must run /sbin/rc sysinit to initialize the system. The /sbin/rc script takes care of the initialisation, so you might say that init doesn't do much -- it delegates the task of initialising the system to another process.
Second, init executed all scripts that had symbolic links in /etc/runlevels/boot. This is defined in the following line:
Code Listing 1.2: The system initialisation, continued rc::bootwait:/sbin/rc bootAgain the rc script performs the necessary tasks. Note that the option given to rc (boot) is the same as the subdirectory of /etc/runlevels that is used.
Now init checks its configuration file to see what runlevel it should run. To decide this, it reads the following line from /etc/inittab:
Code Listing 1.3: The initdefault line id:3:initdefault:In this case (which the majority of Gentoo users will use), the runlevel id is 3. Using this information, init checks what it must run to start runlevel 3:
Code Listing 1.4: The runlevel definitions l0:0:wait:/sbin/rc shutdown l1:S1:wait:/sbin/rc single l2:2:wait:/sbin/rc nonetwork l3:3:wait:/sbin/rc default l4:4:wait:/sbin/rc default l5:5:wait:/sbin/rc default l6:6:wait:/sbin/rc rebootThe line that defines level 3, again, uses the rc script to start the services (now with argument default). Again note that the argument of rc is the same as the subdirectory from /etc/runlevels.
When rc has finished, init decides what virtual consoles it should activate and what commands need to be run at each console:
Code Listing 1.5: The virtual consoles definition c1:12345:respawn:/sbin/agetty 38400 tty1 linux c2:12345:respawn:/sbin/agetty 38400 tty2 linux c3:12345:respawn:/sbin/agetty 38400 tty3 linux c4:12345:respawn:/sbin/agetty 38400 tty4 linux c5:12345:respawn:/sbin/agetty 38400 tty5 linux c6:12345:respawn:/sbin/agetty 38400 tty6 linuxYou have seen that init uses a numbering scheme to decide what runlevel it should activate. A runlevel is a state in which your system is running and contains a collection of scripts (runlevel scripts or initscripts) that must be executed when you enter or leave a runlevel.
In Gentoo, there are seven runlevels defined: three internal runlevels, and four user-defined runlevels. The internal runlevels are called sysinit, shutdown and reboot and do exactly what their names imply: initialize the system, powering off the system and rebooting the system.
The user-defined runlevels are those with an accompanying /etc/runlevels subdirectory: boot, default, nonetwork and single. The boot runlevel starts all system-necessary services which all other runlevels use. The remaining three runlevels differ in what services they start: default is used for day-to-day operations, nonetwork is used in case no network connectivity is required, and single is used when you need to fix the system.
The scripts that the rc process starts are called init scripts. Each script in /etc/init.d can be executed with the arguments start, stop, restart, pause, zap, status, ineed, iuse, needsme, usesme or broken.
To start, stop or restart a service (and all depending services), start, stop and restart should be used:
Code Listing 1.6: Starting Postfix # /etc/init.d/postfix start
Note: Only the services that need the given service are stopped or restarted. The other depending services (those that use the service but don't need it) are left untouched. If you want to stop a service, but not the services that depend on it, you can use the pause argument:
Code Listing 1.7: Stopping Postfix but keep the depending services running # /etc/init.d/postfix pauseIf you want to see what status a service has (started, stopped, paused, ...) you can use the status argument:
Code Listing 1.8: Status information for postfix # /etc/init.d/postfix statusIf the status information tells you that the service is running, but you know that it is not, then you can reset the status information to "stopped" with the zap argument:
Code Listing 1.9: Resetting status information for postfix # /etc/init.d/postfix zapTo also ask what dependencies the service has, you can use iuse or ineed. With ineed you can see the services that are really necessary for the correct functioning of the service. iuse on the other hand shows the services that can be used by the service, but are not necessary for the correct functioning.
Code Listing 1.10: Requesting a list of all necessary services on which Postfix depends # /etc/init.d/postfix ineedSimilarly, you can ask what services require the service (needsme) or can use it (usesme):
Code Listing 1.11: Requesting a list of all services that require Postfix # /etc/init.d/postfix needsmeFinally, you can ask what dependencies the service requires that are missing:
Code Listing 1.12: Requesting a list of missing dependencies for Postfix # /etc/init.d/postfix broken4.b. Working with rc-update
Gentoo's init system uses a dependency-tree to decide what service needs to be started first. As this is a tedious task that we wouldn't want our users to have to do manually, we have created tools that ease the administration of the runlevels and init scripts.
With rc-update you can add and remove init scripts to a runlevel. The rc-update tool will then automatically ask the depscan.sh script to rebuild the dependency tree.
You have already added init scripts to the "default" runlevel during the installation of Gentoo. At that time you might not have had a clue what the "default" is for, but now you should. The rc-update script requires a second argument that defines the action: add, del or show.
To add or remove an init script, just give rc-update the add or del argument, followed by the init script and the runlevel. For instance:
Code Listing 2.1: Removing Postfix from the default runlevel # rc-update del postfix defaultThe rc-update -v show command will show all the available init scripts and list at which runlevels they will execute:
Code Listing 2.2: Receiving init script information # rc-update -v showYou can also run rc-update show (without -v) to just view enabled init scripts and their runlevels.
4.c. Configuring Services
Why the Need for Extra Configuration?
Init scripts can be quite complex. It is therefore not really desirable to have the users edit the init script directly, as it would make it more error-prone. It is however important to be able to configure such a service. For instance, you might want to give more options to the service itself.
A second reason to have this configuration outside the init script is to be able to update the init scripts without the fear that your configuration changes will be undone.
Gentoo provides an easy way to configure such a service: every init script that can be configured has a file in /etc/conf.d. For instance, the apache2 initscript (called /etc/init.d/apache2) has a configuration file called /etc/conf.d/apache2, which can contain the options you want to give to the Apache 2 server when it is started:
Code Listing 3.1: Variable defined in /etc/conf.d/apache2 APACHE2_OPTS="-D PHP5"Such a configuration file contains variables and variables alone (just like /etc/make.conf), making it very easy to configure services. It also allows us to provide more information about the variables (as comments).
4.d. Writing Init Scripts
No, writing an init script is usually not necessary as Gentoo provides ready-to-use init scripts for all provided services. However, you might have installed a service without using Portage, in which case you will most likely have to create an init script.
Do not use the init script provided by the service if it isn't explicitly written for Gentoo: Gentoo's init scripts are not compatible with the init scripts used by other distributions!
The basic layout of an init script is shown below.
Code Listing 4.1: Basic layout of an init script #!/sbin/runscript depend() { (Dependency information) } start() { (Commands necessary to start the service) } stop() { (Commands necessary to stop the service) } restart() { (Commands necessary to restart the service) }Any init script requires the start() function to be defined. All other sections are optional.
There are two dependencies you can define: use and need. As we have mentioned before, the need dependency is more strict than the use dependency. Following this dependency type you enter the service you depend on, or the virtual dependency.
A virtual dependency is a dependency that a service provides, but that is not provided solely by that service. Your init script can depend on a system logger, but there are many system loggers available (metalogd, syslog-ng, sysklogd, ...). As you cannot need every single one of them (no sensible system has all these system loggers installed and running) we made sure that all these services provide a virtual dependency.
Let us take a look at the dependency information for the postfix service.
Code Listing 4.2: Dependency information for Postfix depend() { need net use logger dns provide mta }As you can see, the postfix service:
- requires the (virtual) net dependency (which is provided by, for instance, /etc/init.d/net.eth0)
- uses the (virtual) logger dependency (which is provided by, for instance, /etc/init.d/syslog-ng)
- uses the (virtual) dns dependency (which is provided by, for instance, /etc/init.d/named)
- provides the (virtual) mta dependency (which is common for all mail servers)
In some cases you might not require a service, but want your service to be started before (or after) another service if it is available on the system (note the conditional - this is no dependency anymore) and run in the same runlevel (note the conditional - only services in the same runlevel are involved). You can provide this information using the before or after settings.
As an example we view the settings of the Portmap service:
Code Listing 4.3: The depend() function in the Portmap service depend() { need net before inetd before xinetd }You can also use the "*" glob to catch all services in the same runlevel, although this isn't advisable.
Code Listing 4.4: Running an init script as first script in the runlevel depend() { before * }If your service must write to local disks, it should need localmount. If it places anything in /var/run such as a pidfile, then it should start after bootmisc:
Code Listing 4.5: Example depend() function depend() { need localmount after bootmisc }Next to the depend() functionality, you also need to define the start() function. This one contains all the commands necessary to initialize your service. It is advisable to use the ebegin and eend functions to inform the user about what is happening:
Code Listing 4.6: Example start() function start() { ebegin "Starting my_service" start-stop-daemon --start --exec /path/to/my_service \ --pidfile /path/to/my_pidfile eend $? }Both --exec and --pidfile should be used in start and stop functions. If the service does not create a pidfile, then use --make-pidfile if possible, though you should test this to be sure. Otherwise, don't use pidfiles. You can also add --quiet to the start-stop-daemon options, but this is not recommended unless the service is extremely verbose. Using --quiet may hinder debugging if the service fails to start.
Note: Make sure that --exec actually calls a service and not just a shell script that launches services and exits -- that's what the init script is supposed to do. If you need more examples of the start() function, please read the source code of the available init scripts in your /etc/init.d directory.
Other functions you can define are: stop() and restart(). You are not obliged to define these functions! Our init system is intelligent enough to fill these functions by itself if you use start-stop-daemon.
Although you do not have to create a stop() function, here is an example:
Code Listing 4.7: Example stop() function stop() { ebegin "Stopping my_service" start-stop-daemon --stop --exec /path/to/my_service \ --pidfile /path/to/my_pidfile eend $? }If your service runs some other script (for example, bash, python, or perl), and this script later changes names (for example, foo.py to foo), then you will need to add --name to start-stop-daemon. You must specify the name that your script will be changed to. In this example, a service starts foo.py, which changes names to foo:
Code Listing 4.8: A service that starts the foo script start() { ebegin "Starting my_script" start-stop-daemon --start --exec /path/to/my_script \ --pidfile /path/to/my_pidfile --name foo eend $? }start-stop-daemon has an excellent man page available if you need more information:
Code Listing 4.9: Getting the man page for start-stop-daemon $ man start-stop-daemonGentoo's init script syntax is based on the Bourne Again Shell (bash) so you are free to use bash-compatible constructs inside your init script. However, you may want to write your init scripts to be POSIX-compliant. Future init script systems may allow symlinking /bin/sh to other shells besides bash. Init scripts that rely on bash-only features will then break these configurations.
If you want your init script to support more options than the ones we have already encountered, you should add the option to the opts variable, and create a function with the same name as the option. For instance, to support an option called restartdelay:
Code Listing 4.10: Supporting the restartdelay option opts="${opts} restartdelay" restartdelay() { stop sleep 3 # Wait 3 seconds before starting again start }Service Configuration Variables
You don't have to do anything to support a configuration file in /etc/conf.d: if your init script is executed, the following files are automatically sourced (i.e. the variables are available to use):
- /etc/conf.d/<your init script>
- /etc/conf.d/basic
- /etc/rc.conf
Also, if your init script provides a virtual dependency (such as net), the file associated with that dependency (such as /etc/conf.d/net) will be sourced too.
4.e. Changing the Runlevel Behaviour
Many laptop users know the situation: at home you need to start net.eth0 while you don't want to start net.eth0 while you're on the road (as there is no network available). With Gentoo you can alter the runlevel behaviour to your own will.
For instance you can create a second "default" runlevel which you can boot that has other init scripts assigned to it. You can then select at boottime what default runlevel you want to use.
First of all, create the runlevel directory for your second "default" runlevel. As an example we create the offline runlevel:
Code Listing 5.1: Creating a runlevel directory # mkdir /etc/runlevels/offlineAdd the necessary init scripts to the newly created runlevels. For instance, if you want to have an exact copy of your current default runlevel but without net.eth0:
Code Listing 5.2: Adding the necessary init scripts (Copy all services from default runlevel to offline runlevel) # cd /etc/runlevels/default # for service in *; do rc-update add $service offline; done (Remove unwanted service from offline runlevel) # rc-update del net.eth0 offline (Display active services for offline runlevel) # rc-update show offline (Partial sample Output) acpid | offline domainname | offline local | offline net.eth0 |Even though net.eth0 has been removed from the offline runlevel, udev will still attempt to start any devices it detects and launch the appropriate services. Therefore, you will need to add each network service you do not want started (as well as services for any other devices that may be started by udev) to /etc/conf.d/rc as shown.
Code Listing 5.3: Disabling device initiated services in /etc/conf.d/rc RC_COLDPLUG="yes" (Next, specify the services you do not want automatically started) RC_PLUG_SERVICES="!net.eth0"
Note: For more information on device initiated services, please see the comments inside /etc/conf.d/rc. Now edit your bootloader configuration and add a new entry for the offline runlevel. For instance, in /boot/grub/grub.conf:
Code Listing 5.4: Adding an entry for the offline runlevel title Gentoo Linux Offline Usage root (hd0,0) kernel (hd0,0)/kernel-2.4.25 root=/dev/hda3 softlevel=offlineVoilà, you're all set now. If you boot your system and select the newly added entry at boot, the offline runlevel will be used instead of the default one.
Using bootlevel is completely analogous to softlevel. The only difference here is that you define a second "boot" runlevel instead of a second "default" runlevel.
Google matched content |
Red Hat and Fedora startup scripts
SDB-How to Create Your Own Init Script - openSUSE
Gentoo Linux Documentation -- Initscripts
Managing Linux daemons with init scripts | Linux.com
Adding a startup script to be run at bootup " Ubuntu Blog
7.5. Init Scripts - SUSE LINUX 9.3
Creating startup scripts - LQWiki
Unofficial SUSEFAQ - Starting and Stoping Services- insserv
Red Hat Magazine | Run-levels- Create, use, modify, and master
linux - How do I create a service using chkconfig in CentOS ...
UnixTutorials - Search results for- Create your own init.d scripts
Managing Initscripts with Red Hat's chkconfig | Linux Journal
Booting UNIX- Loading the Kernel.
4.2. Standard Server Configurations
Ubuntu Manpage boot-scripts - General description of boot sequence
Linux- Create your own init.d scripts | Hackosis
Tony's Cafe " Blog Archive " Creating a Daemon in Debian Linux
Linux- How to write a System V init script to start, stop, and ...
Suse
Mobily Playground - How to create your own YouTube search engine
Society
Groupthink : Two Party System as Polyarchy : Corruption of Regulators : Bureaucracies : Understanding Micromanagers and Control Freaks : Toxic Managers : Harvard Mafia : Diplomatic Communication : Surviving a Bad Performance Review : Insufficient Retirement Funds as Immanent Problem of Neoliberal Regime : PseudoScience : Who Rules America : Neoliberalism : The Iron Law of Oligarchy : Libertarian Philosophy
Quotes
War and Peace : Skeptical Finance : John Kenneth Galbraith :Talleyrand : Oscar Wilde : Otto Von Bismarck : Keynes : George Carlin : Skeptics : Propaganda : SE quotes : Language Design and Programming Quotes : Random IT-related quotes : Somerset Maugham : Marcus Aurelius : Kurt Vonnegut : Eric Hoffer : Winston Churchill : Napoleon Bonaparte : Ambrose Bierce : Bernard Shaw : Mark Twain Quotes
Bulletin:
Vol 25, No.12 (December, 2013) Rational Fools vs. Efficient Crooks The efficient markets hypothesis : Political Skeptic Bulletin, 2013 : Unemployment Bulletin, 2010 : Vol 23, No.10 (October, 2011) An observation about corporate security departments : Slightly Skeptical Euromaydan Chronicles, June 2014 : Greenspan legacy bulletin, 2008 : Vol 25, No.10 (October, 2013) Cryptolocker Trojan (Win32/Crilock.A) : Vol 25, No.08 (August, 2013) Cloud providers as intelligence collection hubs : Financial Humor Bulletin, 2010 : Inequality Bulletin, 2009 : Financial Humor Bulletin, 2008 : Copyleft Problems Bulletin, 2004 : Financial Humor Bulletin, 2011 : Energy Bulletin, 2010 : Malware Protection Bulletin, 2010 : Vol 26, No.1 (January, 2013) Object-Oriented Cult : Political Skeptic Bulletin, 2011 : Vol 23, No.11 (November, 2011) Softpanorama classification of sysadmin horror stories : Vol 25, No.05 (May, 2013) Corporate bullshit as a communication method : Vol 25, No.06 (June, 2013) A Note on the Relationship of Brooks Law and Conway Law
History:
Fifty glorious years (1950-2000): the triumph of the US computer engineering : Donald Knuth : TAoCP and its Influence of Computer Science : Richard Stallman : Linus Torvalds : Larry Wall : John K. Ousterhout : CTSS : Multix OS Unix History : Unix shell history : VI editor : History of pipes concept : Solaris : MS DOS : Programming Languages History : PL/1 : Simula 67 : C : History of GCC development : Scripting Languages : Perl history : OS History : Mail : DNS : SSH : CPU Instruction Sets : SPARC systems 1987-2006 : Norton Commander : Norton Utilities : Norton Ghost : Frontpage history : Malware Defense History : GNU Screen : OSS early history
Classic books:
The Peter Principle : Parkinson Law : 1984 : The Mythical Man-Month : How to Solve It by George Polya : The Art of Computer Programming : The Elements of Programming Style : The Unix Hater’s Handbook : The Jargon file : The True Believer : Programming Pearls : The Good Soldier Svejk : The Power Elite
Most popular humor pages:
Manifest of the Softpanorama IT Slacker Society : Ten Commandments of the IT Slackers Society : Computer Humor Collection : BSD Logo Story : The Cuckoo's Egg : IT Slang : C++ Humor : ARE YOU A BBS ADDICT? : The Perl Purity Test : Object oriented programmers of all nations : Financial Humor : Financial Humor Bulletin, 2008 : Financial Humor Bulletin, 2010 : The Most Comprehensive Collection of Editor-related Humor : Programming Language Humor : Goldman Sachs related humor : Greenspan humor : C Humor : Scripting Humor : Real Programmers Humor : Web Humor : GPL-related Humor : OFM Humor : Politically Incorrect Humor : IDS Humor : "Linux Sucks" Humor : Russian Musical Humor : Best Russian Programmer Humor : Microsoft plans to buy Catholic Church : Richard Stallman Related Humor : Admin Humor : Perl-related Humor : Linus Torvalds Related humor : PseudoScience Related Humor : Networking Humor : Shell Humor : Financial Humor Bulletin, 2011 : Financial Humor Bulletin, 2012 : Financial Humor Bulletin, 2013 : Java Humor : Software Engineering Humor : Sun Solaris Related Humor : Education Humor : IBM Humor : Assembler-related Humor : VIM Humor : Computer Viruses Humor : Bright tomorrow is rescheduled to a day after tomorrow : Classic Computer Humor
The Last but not Least Technology is dominated by two types of people: those who understand what they do not manage and those who manage what they do not understand ~Archibald Putt. Ph.D
Copyright © 1996-2021 by Softpanorama Society. www.softpanorama.org was initially created as a service to the (now defunct) UN Sustainable Development Networking Programme (SDNP) without any remuneration. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.
FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available to advance understanding of computer science, IT technology, economic, scientific, and social issues. We believe this constitutes a 'fair use' of any such copyrighted material as provided by section 107 of the US Copyright Law according to which such material can be distributed without profit exclusively for research and educational purposes.
This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...
|
You can use PayPal to to buy a cup of coffee for authors of this site |
Disclaimer:
The statements, views and opinions presented on this web page are those of the author (or referenced source) and are not endorsed by, nor do they necessarily reflect, the opinions of the Softpanorama society. We do not warrant the correctness of the information provided or its fitness for any purpose. The site uses AdSense so you need to be aware of Google privacy policy. You you do not want to be tracked by Google please disable Javascript for this site. This site is perfectly usable without Javascript.
Last modified: March 12, 2019