Our traditional method of writing programs is to create a single and fully functional program and try to provide functions that can fully meet the needs in a program. Such an approach will cause huge and complex programs, reduced maintainability. Generally, programs on windows have comprehensive functions and do not need to work with other programs. For example, if two programs require paging, they will develop a paging module, instead of seeking for the shared paging function. In the Unix world, the opposite is true. Each program only provides a single function and does nothing else. Complex functions are completed through the combination of multiple programs (through pipelines ). I believe that people who often use the Unix command line tool will often feel deeply shocked and admired for its strength and flexibility. For example:
A file contains many URLs with one URL per line, many of which are repeated (for example, access log of a website, and some URLs are accessed multiple times ). How can I extract the top 10 most visited URLs?
$ Sort access. log | uniq-c | sort-Rn | HEAD
The first sort is responsible for sorting and the same URLs are all together. uniq-C calculates the number of occurrences of each URL and attaches the value of occurrences to each URL; the second sort is sorted by the number of occurrences of each URL from the top to the bottom; the first 10 URLs are obtained from the head.
This is a perfect and beautiful combination. Each Command performs its own duties and does its own thing well, but every command knows nothing about the whole thing to do. What they know is that some data comes in, processes it, And then outputs some data. These commands are combined to complete the functions you want to complete.
The combination of shell commands can do countless things. For example:
View the disk space of the current file system?
$ Du -- Max-depth = 4/home | sort-Nr | more
Kill a specific process based on the regular expression:
$ PS xww | grep "Sleep" | cut-C1-5 | xargs-I kill {} 2>/dev/null
A c program that can be compiled and run in Real Time:
$ Echo 'main () {printf ("Hello/N");} '| gcc-w-x C-;./A. Out
And so on...
Many things are clumsy or difficult to accomplish on other operating systems, either having to program themselves or turning to specialized tools. In UNIX operating systems, you can simply tap a few commands, which is also one of the reasons Unix/Linux enjoys.
So where can this power and flexibility come from?
1. Each command only does one thing, which is equivalent to providing basic functions;
2. It provides a flexible combination of methods to combine the functions of various commands through pipeline.
The reason these programs can work seamlessly is that all commands comply with the unified Input and Output representation (for each command program, the input content is text separated by line breaks, the method of work is to process one line in a row, and the output is also text separated by line breaks. This ensures that the output result can be used as input to programs that comply with the same conventions, this provides a seamless combination of methods ). This method also provides scalability. in a specific situation, if the existing commands are still not enough, you can easily add new commands, as long as your program complies with the same conventions, it can work perfectly with existing Unix commands.
According to the three elements of language (basic elements, combination means, and abstract means), Unix command lines provide at least two elements (basic elements and combination means ). Therefore, it can flexibly complete a lot of work.
PS:
Unified Representation is powerful.
In the lisp language, all data is list, and even the lisp code itself is represented as a list. LISP provides built-in list operations, which are powerful and flexible, making lisp popular for half a century (including its successor scheme and Common LISP ).
It is said that in the 60 or 70 s, there was a language popular with programmers, named APL. In this language, all the data is arrays, it also provides a set of unified and convenient operators for various types of Generic Array Operations.