Softpanorama

Home Switchboard Unix Administration Red Hat TCP/IP Networks Neoliberalism Toxic Managers
May the source be with you, but remember the KISS principle ;-)
Bigger doesn't imply better. Bigger often is a sign of obesity, of lost control, of overcomplexity, of cancerous cells

Finding files and directories; mass operations on files

News Red Hat Certification Program Understanding and using essential tools Access a shell prompt and issue commands with correct syntax Finding Help Managing files in RHEL Working with hard and soft links Working with archives and compressed files Using the Midnight Commander as file manager
Text files processing Using redirection and pipes Use grep and extended regular expressions to analyze text files Connecting to the server via ssh, using multiple consoles and screen command Introduction to Unix permissions model Examples of Usage of Unix Find Command Unix find tutorial: Find search expressions Finding files using file name or path Finding SUID/SGUID files
Unix Find Tutorial Selecting files using their age Using -exec option with find Finding Files based on size: largest, empty and within certain range Finding World Writable, Abandoned and other Abnormal Files        
xargs Command Tutorial       Tips Sysadmin Horror Stories Unix History with some Emphasis on Scripting Humor Etc

Extracted from Professor Nikolai Bezroukov unpublished lecture notes.

Copyright 2010-2018, Dr. Nikolai Bezroukov. This is a fragment of the copyrighted unpublished work. All rights reserved.

The Linux find command searches for files that meet specific conditions such as files with a certain name or files greater than a certain size. Like grep find  can be implemented in any scripting language, but this is a more difficult task. If we are talking about shell find is similar to the following ls command piped into a loop, but of course it is more sophisticated, powerful and efficient that this script (here variable $MATCH contain the condition string for which we search):

ls --recursive | while read FILE ; do
     # test file for a match
    if [[ $MATCH ]] ; then
       printf "%s\n" "$FILE"
    fi
done

This script recursively searches directories under the current directory, looking for a filename that matches some condition called MATCH.

From the point of view of computer science find is an interpreter of its own language for specifying queries, which is pretty flexible and powerful but is highly idiosyncratic -- it is used only in find.

This is a unique case when on command line you specify not a set of options, but a query in an application-specific language. The order of components (called predicates) is important. Each predicate iether checks for specific condition (in this case it returns true of false for each file checked), or perform specific action on file that already "passed" previous conditions (in this case it is always returns true).  While essentially any find query is a logical expression, we can also can view it as a pipeline, when each check serves as a filter and cuts file that do no satisfy specified by it criteria. 

Using "find application specific language you can create complex logical expressions describing the qualities of the files, By default they are connected with AND, but if needed you can also specify set of expressions connected by OR logical operation.

Some predicates are, in essence, a regular options which change the overall behavior of find (for example, option mount prohibits following mound points in filesystem traversal). By default find executes the action -print at the end sending the result to STDIN. There are several other  "actions" like -ls or -exec  .  While file can's accept stdin as input stream -- it generated input steam internally by traversing the filesystem, it can pass it s output to the pipe. In this sense it can be called "semi-filter". And in this role it is widely used as the first stage in pipes.

Find predicates

The most commonly used predicate in find is  -name, which compares the name of the file (without path) with a string or regex and returns true or false as a result of this comparison. If you want to evaluate regular expression against the whole path you need to use the predicate -regex  instead.

Theoretically the type of regex in find is user-definable and can be changed with the option -regextype. which allows file  types of regex:

The problem is that in version of find that I tested this option does nothing, and the only type of regex find accepts is basic regex. For example

find -regextype posix-extended /etc -name '^[a-z].*\.[0-9]+$'> # -- DOES NOT WORK. Should find all files in /etc that start with the letter and have numeric suffix

If regular expression is specified, is should be enclosed in quotation marks to prevent the shell from expanding it before the find command:

find /etc -name "*.conf"

The example above find will list names of all objects in the /etc directories  (file, directories, symlinks, etc) that ends with .conf. We probably do not need to list directories and symlinks, so we better add option -type  to limit search to just regular files. The -type f  is the most common option used is find searches. The type can also be b (block device), c (character device), d (directory), p (pipe), l (symbolic link), or s (socket).

find / -name "*.conf"  -type f

In this example the two predicates  -name "*.conf" and -type f  form a simple find expression.  As we already mentioned above,  individual predicates in the expression are connected with logical AND. They are evaluated from left to right.  some predicates like -maxdepth affect the amount of traverse files and should always  be specified first.

So for a file  to get to the end of the expression (were implicit -print predicate will be executed on file) a file should meet both of these conditions: it should have suffix "conf" and be a regular file.

To reverse the condition you can use to prefix it with -not.

find / -name "*.conf"  -not -type f

To specify  -or condition you need to use round brackets (as shell interprets round brackets as metasymbols too, they need to be escaped or put in  quotes)

find /etc \( type f -or type l \)

Summarizing the predicate can be organized into:

For example, to count the number of regular files and directories, do this:

[root@test01 etc]# find /etc -name "*.conf" '(' -type f  -or -type d ')' | wc -l

The number of files without suffix .conf  can be counted as well.

find . ! -name "*.conf" -type f | wc -l

Parentheses must be escaped by a backslash or quotes to prevent Bash from interpreting them as a subshell. Using parentheses, the number of files ending in .txt or .sh can be expressed as

$ find . '(' -name "*.conf" -or -name '*.config' ')' -type f | wc -l

Find as poor man "detective", timestamps related predicates

With so many files in the typical linux filesystem finding  missing files is a regular pasture of sysadmins. Usually you  remember several facts about missing file. among them:

There are several predicates in find which can be to test files of iether the access (atime) or modification time(mtime), which is the time a file was last read or written stored in the inode.  There is also the third time stand called creation time ("ctime") which actually is not attribute of the file but a directory in which file is listed and is nothing more then a date when the particular record in the directory was created. 

Fins provides reasonably flexible capabilities of specifying need time interval iether  in days or minutes. Historically, find times were measured in days (ctime, mtime) in connection with the other file ( -newer), but the GNU version extended this capability provided options that allow specify the tike interval in hours (like -min switch).

 find can look for files that were created or modified exactly in the specified interval, older then certain threshold, or newer then certain threshold.

the most common are check for modified time. You can check the modified time, which is the time a file was last written to, by using -newer, -mtime, and -mmin. The -newer switch checks to see whether one file was modified more recently than a specified file. -mtime tests the number of days ago a file was accessed. -mmin allows to specified minutes inread of days.

In other words, i a plus sign (+) precedes the amount of time, find searches for times greater than this amount. If a minus sign (-) precedes the time measurement, find searches for times less than this amount.  Likewise, -min -5 in minutes means “younger than 5 minutes” or “zero to four minutes old”.

In addition to modification time can use the similar conditions with  the creation time. The relevant options are -cnewer, -ctime, and -cmin. The inode timestamp usually, but not always, represents the time the file was created.

Here are options we discussed for reference:

-amin n
File was last accessed n minutes ago.
-anewer file
File was last accessed more recently than file was modified. If file is a symbolic link and the -H  option or the -L  option is in effect, the access time of the file it points to is always used.
-atime n
File was last accessed n*24 hours ago. When find figures out how many 24-hour periods ago the file was last accessed, any fractional part is ignored, so to match -atime +1, a file has to have been accessed at least two days ago.
-cmin n
File's status was last changed n minutes ago.
-cnewer file
File's status was last changed more recently than file was modified. If file is a symbolic link and the -H  option or the -L  option is in effect, the status-change time of the file it points to is always used.
-ctime n
File's status was last changed n*24 hours ago. See the comments for -atime  to understand how rounding affects the interpretation of file status change times.
-empty

File is empty and is either a regular file or a directory.

Searching files of certain  size

The -size predicate tests the size of a file. The default measurement is 512-byte blocks, which is counterintuitive to many users and a common source of errors. Unlike the time-measurement predicates, which have different predicates for different measurements of time, to change the unit of measurement for size you must follow the amount with a b (bytes), c (characters), k (kilobytes), M (megabyte) G (gigabytes).  Like the time measurements, the amount can have a minus sign (-) to test for files smaller than the specified size, or a plus sign (+) to test for larger files.

For example, use this to find log files greater than 1GB:

$ find / -type f  -size +1G

find shows the matching paths on standard output. Historically, the -print  (whihc is the default and can be omitted) or -ls predicates are used to specify format of output. There is also printf option (or action, to be more precise) which allow to print  selected attributes. Printing the paths is the default behavior. As sometime Unix servers often store files from Microsoft Windows where using blanks in filenames are common there is also special option -print0 which allow pipes such filenames to other utilities without automatic splitting them into parts. 

Performing additional actions  of matches files

To perform an action on a successful match, use -exec. The -exec switch runs a program on each matching file and have several modifications:

-exec command ;
Execute command; true if 0 status is returned. All following arguments to find  are taken to be arguments to the command until an argument consisting of ';' is encountered. The string '{}' is replaced by the current file name being processed everywhere it occurs in the arguments to the command, not just in arguments where it is alone, as in some versions of find. Both of these constructions might need to be escaped (with a '\') or quoted to protect them from expansion by the shell. See the EXAMPLES section for examples of the use of the -exec  option. The specified command is run once for each matched file. The command is executed in the starting directory. There are unavoidable security problems surrounding use of the -exec  action; you should use the -execdir  option instead.
-exec command {} +
This variant of the -exec  action runs the specified command on the selected files, but the command line is built by appending each selected file name at the end; the total number of invocations of the command will be much less than the number of matched files. The command line is built in much the same way that xargs  builds its command lines. Only one instance of '{}' is allowed within the command. The command is executed in the starting directory.
-execdir command ;
-execdir command {} +
Like -exec, but the specified command is run from the subdirectory containing the matched file, which is not normally the directory in which you started find. This a much more secure method for invoking commands, as it avoids race conditions during resolution of the paths to the matched files. As with the -exec  action, the '+' form of -execdir  will build a command line to process more than one matched file, but any given invocation of command will only list files that exist in the same subdirectory. If you use this option, you must ensure that your $PATH  environment variable does not reference '.'; otherwise, an attacker can run any commands they like by leaving an appropriately-named file in a directory in which you will run -execdir. The same applies to having entries in $PATH  which are empty or which are not absolute directory names.
-ok command ;
Like -exec  but ask the user first. If the user agrees, run the command. Otherwise just return false. If the command is run, its standard input is redirected from /dev/null.
The response to the prompt is matched against a pair of regular expressions to determine if it is an affirmative or negative response. This regular expression is obtained from the system if the 'POSIXLY_CORRECT' environment variable is set, or otherwise from find's message translations. If the system has no suitable definition, find's own definition will be used. In either case, the interpretation of the regular expression itself will be affected by the environment variables 'LC_CTYPE' (character classes) and 'LC_COLLATE' (character ranges and equivalence classes).
-okdir command ;
Like -execdir  but ask the user first in the same way as for -ok. If the user does not agree, just return false. If the command is run, its standard input is redirected from /dev/null.

 As we already studied grep, we will use examples with grep, but it can be any utility or script.

Here is one simple example to find files with certain IP in /etc/hosts  (note usage of option -H in grep):

$ find /etc -type f -name hosts -exec grep -H -10.10.10.10 {} \;

More than one action can be specified. To show the filename after a grep match, include -print.

$ find . -type f -name "*.txt" -exec grep Table {} \; -print

find expects {} to appear by itself (that is, surrounded by whitespace). It can't be combined with other characters, such as in an attempt to form a new pathname. If this is necessary use wrapper script.

The -ok switch works the same way as -exec except that it asks for your condirmation whether the command should run. you cna view it as a debug option.

$ find . -type f -name "*.txt" -ok rm {} \;
< rm ... ./orders.txt > ? n
< rm ... ./advocacy/linux.txt > ? n
< rm ... ./advocacy/old_orders.txt > ? n
				

The -ls action switch lists the matching files with more detail.

The -printf switch use set of macros which indicate what kind of information about the file to print:

Traversal control

-follow
Deprecated; use the -L  option instead. Dereference symbolic links. Implies -noleaf. The -follow  option affects only those tests which appear after it on the command line. Unless the -H  or -L  option has been specified, the position of the -follow  option changes the behaviour of the -newer  predicate; any files listed as the argument of -newer  will be dereferenced if they are symbolic links. The same consideration applies to -newerXY, -anewer  and -cnewer. Similarly, the -type  predicate will always match against the type of the file that a symbolic link points to rather than the link itself. Using -follow  causes the -lname and -ilname  predicates always to return false.
-ignore_readdir_race
Normally, find  will emit an error message when it fails to stat a file. If you give this option and a file is deleted between the time find  reads the name of the file from the directory and the time it tries to stat the file, no error message will be issued. This also applies to files or directories whose names are given on the command line. This option takes effect at the time the command line is read, which means that you cannot search one part of the filesystem with this option on and part of it with this option off (if you need to do that, you will need to issue two find  commands instead, one with the option and one without it).
-maxdepth levels
Descend at most levels (a non-negative integer) levels of directories below the command line arguments. -maxdepth 0  means only apply the tests and actions to the command line arguments.
-mindepth levels
Do not apply any tests or actions at levels less than levels (a non-negative integer). -mindepth 1  means process all files except the command line arguments.
-mount Don't descend directories on other filesystems. An alternate name for -xdev, for compatibility with some other versions of find.

 

Using find with xargs

The name xargs, pronounced EX-args, means “combine arguments.” xargs builds and executes command lines by gathering together arguments it reads on the standard input. Most often, these arguments are lists of file names generated by find.

This an alterative to using option -exec. The later can dangerous if used directly (for example you can detect level two directories in the deletion list and act accordingly), or it can be slow for a large number of files because the shell is invoked each match, whle most utilities can accept a list of aginments. When you have the option of piping the results to a second command, the execution speed is significantly faster than when using -exec. A pipe generates the results with two commands instead of hundreds or thousands of commands.

Xargs also allows debugging. 

Also some utilities does not accept the list of filenames from the standard input. for example grep is a filter and it treats standard input as the stream to be analyzed, not as the list of files to be processed.  Actually option --switch-stdio-to-filelist for grep would be very useful.

Xargs allot to convert the list of files proficed by find in multiple argumnet for grep or other ustilities invocation.  As suhc is is much better, more modern solution to this problem.

The core functionality of xargs is convert STDIN into iterative calls to whatever program is specified. By default xargs is suppling to each call as much filenames as OS system buffer allows, but you can epscify the exact number.

Let’s say that the output of find is a list of four files, one, two, three, and four. Using xargs, these files could be given to searched by grep  for particular lines much like with -exec option, but in single grep invocation with four arguments,  making processing more efficient and

find | xargs grep pattern
find /var/log -name "*.gz" -type f -size +0 -print | xargs gzip -xv 

Reminder:  -type f matches just plain files, and -size +0 matches files that aren’t zero bytes in size.

Tip

If you have spaces in filenames you need to use -print0 in find and then add an option -0 (zero) to xargs:

find $HOME -name "html" -print0 | xargs -0 grep -i 
For more information see xargs Command Tutorial

Examples (from Bioinformatics Data Skills):
 

There’s one important gotcha with find and xargs: spaces in filenames can break things, because spaces are considered argument separators by xargs. This would lead to a filename like treatment 02.fq being interpreted as two separate arguments, treatment and 02.fq. The find and xargs developers created a clever solution: both allow for the option to use the null byte as a separator. Here is an example of how to run find and xargs using the null byte delimiter:
$ find . -name "samples [AB].txt" -print0 | xargs -0 rm

In addition to this precaution, it’s also wise to simply not use filenames that contain spaces or other strange characters. Simple alphanumeric names with either dashes or underscores are best. To simplify examples, I will omit -print0 and -0, but these should always be used in practice.

Essentially, xargs is splitting the output from find into arguments, and running:

$ rm ./zmaysA_R1-temp.fastq ./zmaysA_R2-temp.fastq \
     ./zmaysC_R1-temp.fastq ./zmaysC_R2-temp.fastq

xargs passes all arguments received through standard in to the supplied program (rm in this example). This works well for programs like rm, touch, mkdir, and others that take multiple arguments. However, other programs only take a single argument at a time. We can set how many arguments are passed to each command call with xargs’s -n argument. For example, we could call rm four separate times (each on one file) with:

$ find . -name "*-temp.fastq" | xargs -n 1 rm

One big benefit of xargs is that it separates the process that specifies the files to operate on (find) from applying a command to these files (through xargs). If we wanted to inspect a long list of files find returns before running rm on all files in this list, we could use:

$ find . -name "*-temp.fastq" > files-to-delete.txt
$ cat files-to-delete.txt
./zmaysA_R1-temp.fastq
./zmaysA_R2-temp.fastq
./zmaysC_R1-temp.fastq
./zmaysC_R2-temp.fastq
$ cat files-to-delete.txt | xargs rm

Another common trick is to use xargs to build commands that are written to a simple Bash script. For example, rather than running rm directly, we could call echo on rm, and then allow xargs to place arguments after this command (remember, xargs’s behavior is very simple: it just places arguments after the command you provide). For example:

$ find . -name "*-temp.fastq" | xargs -n 1 echo "rm -i" > delete-temp.sh
$ cat delete-temp.sh
rm -i ./zmaysA_R1-temp.fastq
rm -i ./zmaysA_R2-temp.fastq
rm -i ./zmaysC_R1-temp.fastq
rm -i ./zmaysC_R2-temp.fastq

Breaking up the task in this way allows us to inspect the commands we’ve built using xargs (because the command xargs runs is echo, which just prints everything). Then, we could run this simple script with:

$ bash delete-temp.sh
remove ./zmaysA_R1-temp.fastq? y
remove ./zmaysA_R2-temp.fastq? y
remove ./zmaysC_R1-temp.fastq? y
remove ./zmaysC_R2-temp.fastq? y

 

Examples

find /tmp -name core -type f -print | xargs /bin/rm -f
Find files named core  in or below the directory /tmp  and delete them. Note that this will work incorrectly if there are any filenames containing newlines, single or double quotes, or spaces.
find /tmp -name core -type f -print0 | xargs -0 /bin/rm -f

Find files named core  in or below the directory /tmp  and delete them, processing filenames in such a way that file or directory names containing single or double quotes, spaces or newlines are correctly handled. The -name  test comes before the -type  test in order to avoid having to call stat(2)  on every file.

find . -type f -exec file '{}' \;

Runs 'file' on every file in or below the current directory. Notice that the braces are enclosed in single quote marks to protect them from interpretation as shell script punctuation. The semicolon is similarly protected by the use of a backslash, though single quotes could have been used in that case also.

find / \
\( -perm -4000 -fprintf /root/suid.txt %#m %u %p\n \) , \
\( -size +100M -fprintf /root/big.txt %-10s %p\n \)

Traverse the filesystem just once, listing setuid files and directories into /root/suid.txt  and large files into /root/big.txt.

find $HOME -mtime 0

Search for files in your home directory which have been modified in the last twenty-four hours. This command works this way because the time since each file was last modified is divided by 24 hours and any remainder is discarded. That means that to match -mtime 0, a file will have to have a modification in the past which is less than 24 hours ago.

find /sbin /usr/sbin -executable \! -readable -print

Search for files which are executable but not readable.
find . -perm 664

Search for files which have read and write permission for their owner, and group, but which other users can read but not write to. Files which meet these criteria but have other permissions bits set (for example if someone can execute the file) will not be matched.
find . -perm -664

Search for files which have read and write permission for their owner and group, and which other users can read, without regard to the presence of any extra permission bits (for example the executable bit). This will match a file which has mode 0777, for example.
find . -perm /222

Search for files which are writable by somebody (their owner, or their group, or anybody else).
find . -perm /220
find . -perm /u+w,g+w
find . -perm /u=w,g=w

All three of these commands do the same thing, but the first one uses the octal representation of the file mode, and the other two use the symbolic form. These commands all search for files which are writable by either their owner or their group. The files don't have to be writable by both the owner and group to be matched; either will do.
find . -perm -220
find . -perm -g+w,u+w

Both these commands do the same thing; search for files which are writable by both their owner and their group.
find . -perm -444 -perm /222 ! -perm /111
find . -perm -a+r -perm /a+w ! -perm /a+x

These two commands both search for files that are readable for everybody ( -perm -444  or -perm -a+r), have at least one write bit set ( -perm /222  or -perm /a+w) but are not executable for anybody ( ! -perm /111  and ! -perm /a+x  respectively).
cd /source-dir
find . -name .snapshot -prune -o \( \! -name *~ -print0 \)|
cpio -pmd0 /dest-dir

This command copies the contents of /source-dir  to /dest-dir, but omits files and directories named .snapshot  (and anything in them). It also omits files or directories whose name ends in ~, but not their contents. The construct -prune -o \( ... -print0 \)  is quite common. The idea here is that the expression before -prune  matches things which are to be pruned. However, the -prune  action itself returns true, so the following -o  ensures that the right hand side is evaluated only for those directories which didn't get pruned (the contents of the pruned directories are not even visited, so their contents are irrelevant). The expression on the right hand side of the -o  is in parentheses only for clarity. It emphasises that the -print0  action takes place only for things that didn't have -prune  applied to them. Because the default 'and' condition between tests binds more tightly than -o, this is the default anyway, but the parentheses help to show what is going on.
find repo/ -exec test -d {}/.svn -o -d {}/.git -o -d {}/CVS ; \
-print -prune
Given the following directory of projects and their associated SCM administrative directories, perform an efficient search for the projects' roots:
repo/project1/CVS
repo/gnu/project2/.svn
repo/gnu/project3/.svn
repo/gnu/project3/src/.svn
repo/project4/.git

In this example, -prune  prevents unnecessary descent into directories that have already been discovered (for example we do not search project3/src because we already found project3/.svn), but ensures sibling directories (project2 and project3) are found.

 

Locating Files

The Linux locate command consults a database and returns a list of all pathnames containing a certain group of characters, much like a fixed-string grep.

[root@test01 etc]# locate ssh_config
/etc/ssh/ssh_config
/usr/share/man/man5/ssh_config.5.gz

The locate database is maintained by a command called updatedb. It is usually executed once a day by Linux distributions. For this reason, locate is very fast but useful only in finding files that are at least one day old.

Locate command  is useful for finding man pages, especially in  non-standard locations. After that you can open them with less.

Gotchas

find /tmp -name core -type f -print | xargs /bin/rm -f
Find files named core  in or below the directory /tmp  and delete them. Note that this will work incorrectly if there are any filenames containing newlines, single or double quotes, or spaces.  So if the is a file "core findings" it will be interpreted two files names
find /tmp -name core -type f -print0 | xargs -0 /bin/rm -f 

Find files named core  in or below the directory /tmp  and delete them, processing filenames in such a way that file or directory names containing single or double quotes, spaces or newlines are correctly handled. The -name  test comes before the -type  test in order to avoid having to call stat(2)  on every file.

find . -type f -exec file '{}' \;

Top Visited
Switchboard
Latest
Past week
Past month

NEWS CONTENTS

Old News ;-)

Recommended Links

Google matched content

Softpanorama Recommended



Etc

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 quotesSomerset Maugham : Marcus Aurelius : Kurt Vonnegut : Eric Hoffer : Winston Churchill : Napoleon Bonaparte : Ambrose BierceBernard 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 DOSProgramming Languages History : PL/1 : Simula 67 : C : History of GCC developmentScripting 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-MonthHow 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-2018 by Dr. Nikolai Bezroukov. www.softpanorama.org was initially created as a service to the (now defunct) UN Sustainable Development Networking Programme (SDNP) in the author free time and 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 make a contribution, supporting development of this site and speed up access. In case softpanorama.org is down you can use the at softpanorama.info

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 author present and former employers, SDNP or any other organization the author may be associated with. 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: November 02, 2018