[关闭]
@mShuaiZhao 2018-03-11T10:01:30.000000Z 字数 21183 阅读 449

The Unix Workbench Week02

Coursera 2018.03


tutorial: https://www.coursera.org/learn/unix/supplement/9Dkik/self-help

1. Self-Help

自助查询,获取命令的帮助。

2. Get Wild

4. Configure

5. Pipes

6. Make

http://makefiletutorial.com/

Once upon a time there were no web browsers, file browsers, start menus, or search bars. When somebody booted up a computer all they got a was a shell prompt, and all of the work they did started from that prompt.
Back then people still loved to share software, but there was always the problem of how software should be installed. The make program is the best attempt at solving this problem, and make’s elegance has carried it so far that it is still in wide use today.

The guiding design goal of make is that in order to install some new piece of software one would:

  1. Download all of the files required for installation into a directory.
  2. cd into that directory.
  3. Run make.

This is accomplished by specifying a file called makefile, which describes the relationships between different files and programs.
In addition to installing programs, make is also useful for creating documents automatically. Let’s build up a makefile that creates a readme.txtfile which is automatically populated with some information about our current directory.

Let’s start by creating a very basic makefile with nano:

  1. cd ~/Documents/Journal
  2. nano makefile
  3. draft_journal_entry.txt:
  4. touch draft_journal_entry.txt

The simple makefile above shows illustrates a rule which has the following general format:

  1. [target]: [dependencies...]
  2. [commands...]

依赖文件。

In the simple example we created draft_journal_entry.txt is the target, a file which is created as the result of the command(s).
It’s very important to note that any commands under a target must be indented with a Tab.
If we don’t use Tabs to indent the commands then make will fail. Let’s save and close the makefile, then we can run the following in the console:

  1. ls
  2. ## makefile

Let’s use the make command with the target we want to be “made” as the only argument:

  1. make draft_journal_entry.txt
  2. ## touch draft_journal_entry.txt
  3. ls
  4. ## draft_journal_entry.txt
  5. ## makefile

The commands that are indented under our definition of the rule for the draft_journal_entry.txt target were executed, so now draft_journal_entry.txt exists! Let’s try running the same make command again:

  1. make draft_journal_entry.txt
  2. ## make: 'draft_journal_entry.txt' is up to date.

Since the target file already exists no action is taken, and instead we’re informed that the rule for draft_journal_entry.txt is “up to date” (there’s nothing to be done).

If we look at the general rule format we previously sketched out, we can see that we didn’t specify any dependencies for this rule.
上述命令没有添加任何依赖项。
A dependency is a file that the target depends on in order to be built. If a dependency has been updated since the last time make was run for a target then the target is not “up to date.”
依赖项有改变,命令重新执行。
This means that the commands for that target will be run the next time make is run for that target.
This way, the changes to the dependency are incorperated into the target. The commands are only run when the dependencies or change, or when the target doesn’t exist at all, in order to avoid running commands unnecessarily.

Let’s update our makefile to include a readme.txt that is built automatically. First, let’s add a table of contents for our journal:

  1. echo "1. 2017-06-15-In-Boston" > toc.txt

Now let’s update our makefile with nano to automatically generate a readme.txt:

  1. nano makefile
  2. draft_journal_entry.txt:
  3. touch draft_journal_entry.txt
  4. readme.txt: toc.txt
  5. echo "This journal contains the following number of entries:" > readme.txt
  6. wc -l toc.txt | egrep -o "[0-9]+" >> readme.txt

Take note that the -o flag provided to egrep above extracts the regular expression match from the matching line, so that only the number of lines is appended to readme.txt. Now let’s run make with readme.txt as the target:

  1. make readme.txt
  2. ## echo "This journal contains the following number of entries:" > readme.txt
  3. ## wc -l toc.txt | egrep -o "[0-9]+" >> readme.txt

Now let’s take a look at readme.txt:

  1. cat readme.txt
  2. ## This journal contains the following number of entries:
  3. ## 1

Looks like it worked! What do you think will happen if we run make readme.txt again?

  1. make readme.txt
  2. ## make: 'readme.txt' is up to date.

You guessed it: nothing happened! Since the readme.txt file still exists and no changes were made to any of the dependencies for readme.txt (toc.txt is the only dependency) make doesn’t run the commands for the readme.txt rule. Now let’s modify toc.txt then we’ll try running make again.

  1. echo "2. 2017-06-16-IQSS-Talk" >> toc.txt
  2. make readme.txt
  3. ## echo "This journal contains the following number of entries:" > readme.txt
  4. ## wc -l toc.txt | egrep -o "[0-9]+" >> readme.txt

Looks like it ran! Let’s check readme.txt to make sure.

  1. cat readme.txt
  2. ## This journal contains the following number of entries:
  3. ## 2

It looks like make successfully updated readme.txt! With every change to toc.txt, running make readme.txt will programmatically update readme.txt.

In order to simplify the make experience, we can create a rule at the top of our makefile called all where we can list all of the files that are built by the makefile.
By adding the all target we can simply run make without any arguments in order to build all of the targets in the makefile. Let’s open up nano and add this rule:

  1. nano makefile
  2. all: draft_journal_entry.txt readme.txt
  3. draft_journal_entry.txt:
  4. touch draft_journal_entry.txt
  5. readme.txt: toc.txt
  6. echo "This journal contains the following number of entries:" > readme.txt
  7. wc -l toc.txt | egrep -o "[0-9]+" >> readme.txt

While we have nano open let’s add another special rule at the end of our makefile called clean which destroys the files created by our makefile:

  1. all: draft_journal_entry.txt readme.txt
  2. draft_journal_entry.txt:
  3. touch draft_journal_entry.txt
  4. readme.txt: toc.txt
  5. echo "This journal contains the following number of entries:" > readme.txt
  6. wc -l toc.txt | egrep -o "[0-9]+" >> readme.txt
  7. clean:
  8. rm draft_journal_entry.txt
  9. rm readme.txt

Let’s save and close our makefile then let’s test it out first let’s clean up our repository:

  1. make clean
  2. ls
  3. ## rm draft_journal_entry.txt
  4. ## rm readme.txt
  5. ## makefile
  6. ## toc.txt
  7. make
  8. ls
  9. ## touch draft_journal_entry.txt
  10. ## echo "This journal contains the following number of entries:" > readme.txt
  11. ## wc -l toc.txt | egrep -o "[0-9]+" >> readme.txt
  12. ## draft_journal_entry.txt
  13. ## readme.txt
  14. ## makefile
  15. ## toc.txt

Looks like our makefile works! The make command is extremely powerful, and this section is meant to just be an introduction. For more in-depth reading about make I recommend Karl Broman’s tutorial or Chase Lambert’s makefiletutorial.com.

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注