笨办法学 Linux 4~7

2022-12-01 18:51:19 浏览数 (1)

练习 4:Bash:处理文件,pwdlscpmvrmtouch

原文:Exercise 4. Bash: working with files, pwd, ls, cp, mv, rm, touch 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译

在 Linux 中,一切都是文件。但是什么是文件?现在完全可以说,它是一个包含一些信息的对象。它通常定义如下:

计算机文件是用于存储信息的,任意的信息块或资源。它可用于计算机程序,并且通常基于某种持久的存储器。文件是持久的,因为它在当前程序完成后,仍然可用于其它程序。计算机文件可以认为是纸质文档的现代对应物,它们通常保存于办公室和图书馆的文件中,这是该术语的来源。

但这个定义太笼统了,所以让我们更具体一些。man stat告诉我们,文件是一个对象,它包含以下属性:

代码语言:javascript复制
struct stat {
   dev_t     st_dev;     /* ID of device containing file */
   ino_t     st_ino;     /* inode number */
   mode_t    st_mode;    /* protection */
   nlink_t   st_nlink;   /* number of hard links */
   uid_t     st_uid;     /* user ID of owner */
   gid_t     st_gid;     /* group ID of owner */
   dev_t     st_rdev;    /* device ID (if special file) */
   off_t     st_size;    /* total size, in bytes */
   blksize_t st_blksize; /* blocksize for file system I/O */
   blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
   time_t    st_atime;   /* time of last access */
   time_t    st_mtime;   /* time of last modification */
   time_t    st_ctime;   /* time of last status change */
};

不要害怕,只要记住以下属性:

  • 大小,这正好是它所说的。
  • 上次访问的时间,当你查看文件时更新。
  • 上次修改的时间,当你更改文件时更新。

现在你将学习如何打印当前目录,目录中的文件,复制和移动文件。

这样做

代码语言:javascript复制
 1: pwd
 2: ls
 3: ls -a
 4: ls -al
 5: ls -altr
 6: cp -v .bash_history{,1}
 7: cp -v .bash_history1 .bash_history2
 8: mv -v .bash_history1 .bash_history2
 9: rm -v .bash_history2
10: touch .bashrc
11: ls -al
12: ls .*

你应该看到什么

代码语言:javascript复制
Hello, user1!
user1@vm1:~$ pwd
/home/user1
user1@vm1:~$ ls
user1@vm1:~$ ls -a
.  ..  .bash_history  .bash_history1  .bash_logout  .bashrc  .lesshst  .profile  .profile.bak  .profile.bak1
user1@vm1:~$ ls -al
total 40
drwxr-xr-x 2 user1 user1 4096 Jun  7 13:30 .
drwxr-xr-x 3 root  root  4096 Jun  6 21:49 ..
-rw------- 1 user1 user1  853 Jun  7 15:03 .bash_history
-rw------- 1 user1 user1  308 Jun  7 13:14 .bash_history1
-rw-r--r-- 1 user1 user1  220 Jun  6 21:48 .bash_logout
-rw-r--r-- 1 user1 user1 3184 Jun  6 21:48 .bashrc
-rw------- 1 user1 user1   45 Jun  7 13:31 .lesshst
-rw-r--r-- 1 user1 user1  697 Jun  7 12:25 .profile
-rw-r--r-- 1 user1 user1  741 Jun  7 12:19 .profile.bak
-rw-r--r-- 1 user1 user1  741 Jun  7 13:12 .profile.bak1
user1@vm1:~$ ls -altr
total 40
-rw-r--r-- 1 user1 user1 3184 Jun  6 21:48 .bashrc
-rw-r--r-- 1 user1 user1  220 Jun  6 21:48 .bash_logout
drwxr-xr-x 3 root  root  4096 Jun  6 21:49 ..
-rw-r--r-- 1 user1 user1  741 Jun  7 12:19 .profile.bak
-rw-r--r-- 1 user1 user1  697 Jun  7 12:25 .profile
-rw-r--r-- 1 user1 user1  741 Jun  7 13:12 .profile.bak1
-rw------- 1 user1 user1  308 Jun  7 13:14 .bash_history1
drwxr-xr-x 2 user1 user1 4096 Jun  7 13:30 .
-rw------- 1 user1 user1   45 Jun  7 13:31 .lesshst
-rw------- 1 user1 user1  853 Jun  7 15:03 .bash_history
user1@vm1:~$ cp -v .bash_history{,1}
`.bash_history' -> `.bash_history1'
user1@vm1:~$ cp -v .bash_history1 .bash_history2
`.bash_history1' -> `.bash_history2'
user1@vm1:~$ mv -v .bash_history1 .bash_history2
`.bash_history1' -> `.bash_history2'
user1@vm1:~$ rm -v .bash_history2
removed `.bash_history2'
user1@vm1:~$ touch .bashrc
user1@vm1:~$ ls -al
total 36
drwxr-xr-x 2 user1 user1 4096 Jun 14 12:23 .
drwxr-xr-x 3 root  root  4096 Jun  6 21:49 ..
-rw------- 1 user1 user1  853 Jun  7 15:03 .bash_history
-rw-r--r-- 1 user1 user1  220 Jun  6 21:48 .bash_logout
-rw-r--r-- 1 user1 user1 3184 Jun 14 12:24 .bashrc
-rw------- 1 user1 user1   45 Jun  7 13:31 .lesshst
-rw-r--r-- 1 user1 user1  697 Jun  7 12:25 .profile
-rw-r--r-- 1 user1 user1  741 Jun  7 12:19 .profile.bak
-rw-r--r-- 1 user1 user1  741 Jun  7 13:12 .profile.bak1
user1@vm1:~$
user1@vm1:~$ ls .*
.bash_history  .bash_logout  .bashrc  .lesshst  .profile  .profile.bak  .profile.bak1

.:
ls.out

..:
user1

解释

  1. 打印你当前的工作目录,这是你的主目录。请注意它为何不同于user1@vm1:~中的~,这也表示,你在你的home目录中。这是因为~是你的主目录的缩写。
  2. 这里没有任何东西,因为你的主目录中只有隐藏的文件。记住,隐藏的文件是以点开头的名称。
  3. 打印主目录中的所有文件,因为-a参数让ls显示所有文件,包括隐藏文件。
  4. 以长格式打印主目录中的所有文件:权限,所有者,组,大小,时间戳(通常是修改时间)和文件名。
  5. 注意文件如何按日期安排,最新的文件是最后一个。-t告诉ls按时间排序,-r告诉ls反转排序。
  6. .bash_history复制到.bash_history1。这似乎对你来说很神秘,但解释真的很简单。Bash 有一个称为花括号扩展的功能,它有一组规则,定义了如何 处理像{1,2,3}之类的结构。在我们的例子中,.bash_history{,1} 扩展为两个参数,即.bash_history.bash_history1。Bash 仅仅接受花括号前的一个参数,在我们的例子中是.bash_history,并向参数添加花括号里的所有东西,以逗号分隔,并以此作为参数。第一个添加只是变成.bash_history,因为花括号中的第一个参数是空的,没有第一个参数。接下来,Bash 添加了1,因为这是第二个参数,就是这样。扩展后传递给cp的 结果参数为-v .bash_history1 .bash_history2
  7. 这可能对你来说很明显。将最近创建的.bash_history1复制到.bash_history2
  8. .bash_history1移动到.bash_history2。请注意,它会覆盖目标文件而不询问,所以不再有.bash_history2,没有了!
  9. .bashrc时间戳更新为当前日期和时间。这意味着.bashrc的所有时间属性,st_atimest_mtimest_ctime都设置为当前日期和时间。你可以通过输入stat .bashrc来确定它。
  10. 删除.bash_history2。这里没有警告,请小心。另外,总是用-v选项。
  11. 再次以长格式打印所有文件。请注意.bashrc的时间戳更改。
  12. 在你的主目录中以短格式打印文件。请注意,你不仅可以列出/home/user1目录,还可以列出/home目录本身。不要和任何命令一起使用这个结构,特别是 rm,永远不要!或许,你会意外地通过删除错误的文件或更改权限,来使系统崩溃。

附加题

玩转 bash 花括号扩展。从echo test{1,2,foo,bar}开始。尝试使用花括号键入几个单独的参数。

使用 Google 搜索 bash 花括号扩展,从搜索结果中打开“Bash 参考手册”,并阅读相应的部分。

尝试弄清楚ls .*如何和为什么工作。

对自己说10次:“我会一直使用 verbose 选项。verbose 选项通常用作-v参数”。

对自己说10次:“我会永远用ls检查任何危险的命令”。

练习 5:Bash:环境变量,envsetexport

原文:Exercise 5. Bash: environment variables, env, set, export 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译

请考虑以下内容:你希望程序打印出你的用户名。这个程序怎么知道的?在 Linux 中有一些环境变量。这意味着你的 shell 中有许多变量,其中许多变量自动设置,每次运行程序时,其中一些变量将传递给该程序。

详细说明:

  • 一些变量只为你当前的 shell 设置。它们被称为本地 shell 变量。你可以通过键入set,一个 bash 内置命令来列出它们 ,这意味着没有启动其它程序,之后你执行了它。此命令由 bash 本身处理。
  • 其他变量被传递到你从当前 shell 启动的每个程序。它们被称为环境变量,可以通过env程序列出,这意味着,通过键入env, 你将看到,你启动的每个程序获得了什么变量。

你可能想要深入挖掘。要做到这一点,掌握 subshell 的概念,这是一个子进程,当你运行程序时创建,并且成为你的程序。

现在,你将学习如何创建变量以及如何使用变量。

这样做

代码语言:javascript复制
1: foo='Hello World!'
2: echo $foo
3: set | grep foo
4: env | grep foo
5: export foo
6: env | grep foo
7: foo='ls -al'
8: $foo

你会看到什么

代码语言:javascript复制
uset1@vm1:~$ foo='Hello World!'
user1@vm1:~$ echo $foo
Hello World!
user1@vm1:~$ set | grep foo
foo='Hello World!'
user1@vm1:~$ env | grep foo
user1@vm1:~$ export foo
user1@vm1:~$ env | grep foo
foo=Hello World!
user1@vm1:~$ foo='ls -al'
user1@vm1:~$ $foo
total 36
drwxr-xr-x 2 user1 user1 4096 Jun 14 12:23 .
drwxr-xr-x 3 root  root  4096 Jun  6 21:49 ..
-rw------- 1 user1 user1 4042 Jun 15 18:52 .bash_history
-rw-r--r-- 1 user1 user1  220 Jun  6 21:48 .bash_logout
-rw-r--r-- 1 user1 user1 3184 Jun 14 12:24 .bashrc
-rw------- 1 user1 user1   50 Jun 15 18:41 .lesshst
-rw-r--r-- 1 user1 user1  697 Jun  7 12:25 .profile
-rw-r--r-- 1 user1 user1  741 Jun  7 12:19 .profile.bak
-rw-r--r-- 1 user1 user1  741 Jun  7 13:12 .profile.bak1

解释

  1. 创建变量foo ,并将Hello World!这一行放在其中。
  2. 打印出变量foo
  3. 打印所有环境变量的列表,它传递给grep,打印出只包含变量foo的行。注意变量foo存在。
  4. 打印所有环境变量列表,它们传递给你执行的任何程序。注意变量foo不存在。
  5. 使变量foo可用于从当前 shell 执行的所有程序。
  6. 现在你可以看到,你的变量确实可用于你执行的所有程序。
  7. ls /放入变量foo
  8. 执行包含在变量foo中的命令。

附加题

输入并执行envset。看看有多少个不同的变量?不用担心,通常你可以通过谷歌搜索,快速了解一个变量的作用。尝试这样做。

尝试输入:

代码语言:javascript复制
set | egrep '^[[:alpha:]].*$'

现在,试试set。看见我在这里做了什么嘛?快速的解释是:

代码语言:javascript复制
egrep '^[[:alpha:]].*$'

仅仅打印出以字母开头的行,它是每个字母,并忽略其他行。现在不要纠结这个,也不要纠结|符号。以后我会解释它。

在这里阅读envset之间的区别:http://stackoverflow.com/questions/3341372/differnce-between-the-shell-and-environment-variable-in-bash。记住,stackoverflow 是你的朋友!我会重复多次。

尝试输入set FOO=helloworld bash -c 'echo $FOO'。这里是解释:http://stackoverflow.com/questions/10938483/bash-specifying-environment-variables-for-echo-on-command-line。同样,不要太纠结,你会在大量练习之后再次碰到它,我保证。

试试这个:

代码语言:javascript复制
PS1_BAK=$PS1
PS1='Hello, world! $(pwd) > '
PS1=$PS1_BAK

注意我使用$(pwd),将命令输出作为变量访问。现在,键入man bash /PS1(是的,只是斜杠),按下<ENTER>。你现在可以按下n查看下一个结果。浏览 PROMPTING,并键入q来退出man。现在,访问 http://stackexchange.com/ 并搜索bash PS1。了解这两个文档来源的区别。

练习 6:Bash:语言设置,LANGlocaledpkg-reconfigure locales

原文:Exercise 6. Bash: language settings, LANG, locale, dpkg-reconfigure locales 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译

在 Linux 中,语言选择像导出变量一样简单。这是正确的,通过查看这个变量,程序决定如何和你交流。当然,为了使其工作,程序必须支持区域设置,并将其翻译成可用和安装的语言。让我们通过安装法语区域设置,看看它的工作原理。

现在,你将学习如何安装和选择一个区域设置。

这样做

代码语言:javascript复制
1: echo $LANG
2: locale
3: man man # press q to exit man
4: sudo dpkg-reconfigure locales

现在,选择fr_FR.UTF-8 locale,通过使用方向键来浏览列表,并使用看空格来选择区域设置。选择en_US.UTF-8作为默认的系统区域。

代码语言:javascript复制
 5: export LANG=fr_FR.UTF-8
 6: echo $LANG
 7: locale # press q to exit man
 8: man man
 9: export LANG=en_US.UTF-8

你会看到什么

代码语言:javascript复制
user1@vm1:~$ echo $LANG
en_US.UTF-8
user1@vm1:~$ locale
LANG=en_US.UTF-8
LANGUAGE=en_US:en
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
user1@vm1:~$ man man
MAN(1)                Manual pager utils                MAN(1)

NAME
       man - an interface to the on-line reference manuals
user1@vm1:~$ sudo dpkg-reconfigure locales
---------------| Configuring locales |-----------------------
|                                                           |
| Locales are a framework to switch between multiple        |
| languages and allow users to use their language,          |
| country, characters, collation order, etc.                |
|                                                           |
| Please choose which locales to generate. UTF-8 locales    |
| should be chosen by default, particularly for new         |
| installations. Other character sets may be useful for     |
| backwards compatibility with older systems and software.  |
|                                                           |
|                          <Ok>                             |
|                                                           |
-------------------------------------------------------------
           -----------| Configuring locales |--------
           | Locales to be generated:               |
           |                                        |
           |    [ ] fr_BE@euro ISO-8859-15          |
           |    [ ] fr_CA ISO-8859-1                |
           |    [ ] fr_CA.UTF-8 UTF-8               |
           |    [ ] fr_CH ISO-8859-1                |
           |    [ ] fr_CH.UTF-8 UTF-8               |
           |    [*] fr_FR ISO-8859-1                |
           |    [ ] fr_FR.UTF-8 UTF-8               |
           |    [ ] fr_FR@euro ISO-8859-15          |
           |                                        |
           |                                        |
           |        <Ok>            <Cancel>        |
           |                                        |
           ------------------------------------------
 ------------------ Configuring locales ----------------------
 |                                                           |
 | Many packages in Debian use locales to display text in    |
 | the correct language for the user. You can choose a       |
 | default locale for the system from the generated          |
 | locales.                                                  |
 |                                                           |
 | This will select the default language for the entire      |
 | system. If this system is a multi-user system where not   |
 | all users are able to speak the default language, they    |
 | will experience difficulties.                             |
 |                                                           |
 |                          <Ok>                             |
 |                                                           |
 -------------------------------------------------------------
------------ Configuring locales --------------
| Default locale for the system environment:  |
|                                             |
|                 None                        |
|                 en_US.UTF-8                 |
|                 fr_FR.UTF-8                 |
|                                             |
|                                             |
|          <Ok>              <Cancel>         |
|                                             |
-----------------------------------------------
Generating locales (this might take a while)...
  en_US.UTF-8... done
  fr_FR.UTF-8... done
Generation complete.
user1@vm1:~$ export LANG=fr_FR.UTF-8
user1@vm1:~$ echo $LANG
fr_FR.UTF-8
user1@vm1:~$ locale
LANG=fr_FR.UTF-8
LANGUAGE=en_US:en
LC_CTYPE="fr_FR.UTF-8"
LC_NUMERIC="fr_FR.UTF-8"
LC_TIME="fr_FR.UTF-8"
LC_COLLATE="fr_FR.UTF-8"
LC_MONETARY="fr_FR.UTF-8"
LC_MESSAGES="fr_FR.UTF-8"
LC_PAPER="fr_FR.UTF-8"
LC_NAME="fr_FR.UTF-8"
LC_ADDRESS="fr_FR.UTF-8"
LC_TELEPHONE="fr_FR.UTF-8"
LC_MEASUREMENT="fr_FR.UTF-8"
LC_IDENTIFICATION="fr_FR.UTF-8"
LC_ALL=
user1@vm1:~$ man man
MAN(1)  Utilitaires de l'afficheur des pages de manuel  MAN(1)

NOM
       man   -   interface  de  consultation  des  manuels  de
       référence en ligne
user1@vm1:~$ export LANG=en_US.UTF-8
user1@vm1:~$

解释

  1. 打印你当前使用的LANG变量,程序用它来确定与你进行交互时要使用的语言。
  2. 按照指定的国家/地区的格式,打印所有区域变量,程序员使用它们来设置数字,地址,电话格式,以及其它。
  3. 显示 unix 手册系统的手册页。注意我如何使用#来注释一个动作,#之后的所有内容都不执行。
  4. 执行程序来重新配置你的区域设置。因为这个变化是系统层次的,你需要以 root 身份运行这个命令,这就是在dpkg-reconfigure locales前面有sudo的原因。现在不要纠结sudo,我会让你熟悉它。
  5. 导出LANG变量,用于设置所有其他区域变量。
  6. 打印出LANG变量,你可以看到它已经改变了,按照你的预期。
  7. 打印其它已更改的区域变量。
  8. 以法语显示man手册页。
  9. 将`LANG变量恢复为英文。

附加题

  • 阅读区域设置的手册页。为此,请输入man locale
  • 现在,阅读man 7 locale页面。注意我 在这里使用7,来调用关于约定的手册页。如果你愿意, 现在阅读man man,了解其他可能的代码是什么,或者只是等待涵盖它的练习。

练习 7:Bash:重定向,stdinstdoutstderr<>>>|teepv

原文:Exercise 7. Bash: redirection, stdin, stdout, stderr, <, >, >>, |, tee, pv 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译

在 Linux 中,一切都只是文件。这意味着,对于控制台程序:

  • 键盘表示为一个文件,Bash 从中读取你的输入。
  • 显示器表示为一个文件,Bash向输出写入它。

让我们假设,你有一个程序可以计算文件中的行。你可以通过键入wc -l来调用它。现在尝试一下 没有发生什么事吧?它只是卡在那里。错了,它正在等待你的输入。这是它的工作原理:

代码语言:javascript复制
line_counter = 0
while end of file is not reached
    read a line
    add 1 to line_counter
print line_counter

所以wc目前从/dev/tty读取行,这在当前上下文中是你的键盘。每次你按下回车,wc都会获取一行。任意键入几行,然后按CTRL D,这将为wc产生EOF字符,使其明白达到文件末尾。现在它会告诉你你输入了多少行。

但是如果你想计算现有文件中的行呢?那么,这就需要重定向 了!为了在其输入上提供现有文件,请键入以下内容:wc -l < .bash_history。你看,它有作用!真的是那么简单!重定向 是一种机制,允许你告诉程序,将其来自键入输入和/或到显示器的输出,重定向到另一个文件。为此,你可以使用这些特殊命令,然后启动程序:

  • < - 用文件替换标准输入(例如键盘)。
  • > - 用文件替换标准输出(例如显示器)。警告!此命令将覆盖 你的指定文件的内容,因此请小心。
  • >> - 与上面相同,但不是覆盖 文件,而是写入到它的末尾,保存在该文件中已存在的信息。小心不要混淆两者。
  • | - 从一个程序获取输出,并将其连接到另一个程序。这将在下一个练习中详细阐述。

现在,你将学习如何将程序的输入和输出重定向到文件或其他程序。

这样做

代码语言:javascript复制
 1: sudo aptitude install pv
 2: read foo < /dev/tty
 3: Hello World!
 4: echo $foo > foo.out
 5: cat foo.out
 6: echo $foo >> foo.out
 7: cat foo.out
 8: echo > foo.out
 9: cat foo.out
10: ls -al | grep foo
11: ls -al | tee ls.out
12: dd if=/dev/zero of=~/test.img bs=1M count=10
13: pv ~/test.img | dd if=/dev/stdin of=/dev/null bs=1
14: rm -v foo.out
15: rm -v test.img

你应该看到什么

代码语言:javascript复制
user1@vm1:~$ sudo aptitude install pv
The following NEW packages will be installed:
  pv
0 packages upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B/28.9 kB of archives. After unpacking 143 kB will be used.
Selecting previously deselected package pv.
(Reading database ... 39657 files and directories currently installed.)
Unpacking pv (from .../archives/pv_1.1.4-1_amd64.deb) ...
Processing triggers for man-db ...
Setting up pv (1.1.4-1) ...

user1@vm1:~$ read foo < /dev/tty
Hello World!
user1@vm1:~$ echo $foo > foo.out
user1@vm1:~$ cat foo.out
Hello World!
user1@vm1:~$ echo $foo >> foo.out
user1@vm1:~$ cat foo.out
Hello World!
Hello World!
user1@vm1:~$ echo > foo.out
user1@vm1:~$ cat foo.out

user1@vm1:~$ ls -al | grep foo
-rw-r--r-- 1 user1 user1    1 Jun 15 20:03 foo.out
user1@vm1:~$ ls -al | tee ls.out
total 44
drwxr-xr-x 2 user1 user1 4096 Jun 15 20:01 .
drwxr-xr-x 3 root  root  4096 Jun  6 21:49 ..
-rw------- 1 user1 user1 4865 Jun 15 19:34 .bash_history
-rw-r--r-- 1 user1 user1  220 Jun  6 21:48 .bash_logout
-rw-r--r-- 1 user1 user1 3184 Jun 14 12:24 .bashrc
-rw-r--r-- 1 user1 user1    1 Jun 15 20:03 foo.out
-rw------- 1 user1 user1   50 Jun 15 18:41 .lesshst
-rw-r--r-- 1 user1 user1    0 Jun 15 20:03 ls.out
-rw-r--r-- 1 user1 user1  697 Jun  7 12:25 .profile
-rw-r--r-- 1 user1 user1  741 Jun  7 12:19 .profile.bak
-rw-r--r-- 1 user1 user1  741 Jun  7 13:12 .profile.bak1
-rw-r--r-- 1 user1 user1    0 Jun 15 20:02 test.img
user1@vm1:~$ dd if=/dev/zero of=~/test.img bs=1M count=10
10 0 records in
10 0 records out
10485760 bytes (10 MB) copied, 0.0130061 s, 806 MB/s
user1@vm1:~$ pv ~/test.img | dd if=/dev/stdin of=/dev/null bs=1
  10MB 0:00:03 [3.24MB/s] [=================================================================================>] 100%
10485760 0 records in
10485760 0 records out
10485760 bytes (10 MB) copied, 3.10446 s, 3.4 MB/s
user1@vm1:~$ rm -v foo.out
removed `foo.out'
user1@vm1:~$ rm -v test.img
removed `test.img'
user1@vm1:~$

解释

  1. 在你的系统上安装pv(管道查看器)程序,稍后你需要它。
  2. 将你的输入读取到变量foo。这是可能的,因为显示器和键盘实际上是系统的电传打字机。是的,那个电传打字机!在线阅读更多关于tty的东西。
  3. 这是你输入的东西。
  4. foo变量的内容重定向到foo.out文件,在进程中创建文件或覆盖现有文件,而不会警告删除所有内容!
  5. 打印出foo.out的内容。
  6. foo变量的内容重定向到foo.out文件,在进程中创建文件或附加 到现有文件。这是安全的,但不要混淆这两者,否则你会有巨大的悲剧。
  7. 再次打印出foo.out内容。
  8. 将空内容重定向到foo.out,在进程中清空文件。
  9. 显示文件确实是空的。
  10. 列出你的目录并将其通过管道输出到grep。它的原理是,获取所有ls -al的输出,并将其扔给grep。这又称为管道。
  11. 将你的目录列出到屏幕上,并写入ls.out。很有用!
  12. 创建大小为 10 兆字节的清零文件。现在不要纠结它如何工作。
  13. 将这个文件读取到/dev/null,这是你系统中终极的垃圾桶,什么都没有。写入它的一切都会小时。请注意,pv会向你展示读取文件的进程,如果你尝试使用其他命令读取它,你就不会知道它需要多长时间来完成。
  14. 删除foo.out。记得自己清理一下。
  15. 删除test.img

附加题

  • 阅读 stackoverflow 上的管道和重定向,再次阅读 stackoverflow 和 Greg 的 Wiki,这是非常有用的资源,记住它。
  • 打开 bash 的man页面,向下滚动到 REDIRECTION 部分并阅读它。
  • 阅读man pvman tee的描述。

0 人点赞