练习 4:Bash:处理文件,pwd
,ls
,cp
,mv
,rm
,touch
原文:Exercise 4. Bash: working with files, pwd, ls, cp, mv, rm, touch 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译
在 Linux 中,一切都是文件。但是什么是文件?现在完全可以说,它是一个包含一些信息的对象。它通常定义如下:
计算机文件是用于存储信息的,任意的信息块或资源。它可用于计算机程序,并且通常基于某种持久的存储器。文件是持久的,因为它在当前程序完成后,仍然可用于其它程序。计算机文件可以认为是纸质文档的现代对应物,它们通常保存于办公室和图书馆的文件中,这是该术语的来源。
但这个定义太笼统了,所以让我们更具体一些。man stat
告诉我们,文件是一个对象,它包含以下属性:
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
解释
- 打印你当前的工作目录,这是你的主目录。请注意它为何不同于
user1@vm1:~
中的~
,这也表示,你在你的home
目录中。这是因为~
是你的主目录的缩写。 - 这里没有任何东西,因为你的主目录中只有隐藏的文件。记住,隐藏的文件是以点开头的名称。
- 打印主目录中的所有文件,因为
-a
参数让ls
显示所有文件,包括隐藏文件。 - 以长格式打印主目录中的所有文件:权限,所有者,组,大小,时间戳(通常是修改时间)和文件名。
- 注意文件如何按日期安排,最新的文件是最后一个。
-t
告诉ls
按时间排序,-r
告诉ls
反转排序。 - 将
.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
。 - 这可能对你来说很明显。将最近创建的
.bash_history1
复制到.bash_history2
。 - 向
.bash_history1
移动到.bash_history2
。请注意,它会覆盖目标文件而不询问,所以不再有.bash_history2
,没有了! - 将
.bashrc
时间戳更新为当前日期和时间。这意味着.bashrc
的所有时间属性,st_atime
,st_mtime
和st_ctime
都设置为当前日期和时间。你可以通过输入stat .bashrc
来确定它。 - 删除
.bash_history2
。这里没有警告,请小心。另外,总是用-v
选项。 - 再次以长格式打印所有文件。请注意
.bashrc
的时间戳更改。 - 在你的主目录中以短格式打印文件。请注意,你不仅可以列出
/home/user1
目录,还可以列出/home
目录本身。不要和任何命令一起使用这个结构,特别是rm
,永远不要!或许,你会意外地通过删除错误的文件或更改权限,来使系统崩溃。
附加题
玩转 bash 花括号扩展。从echo test{1,2,foo,bar}
开始。尝试使用花括号键入几个单独的参数。
使用 Google 搜索 bash 花括号扩展,从搜索结果中打开“Bash 参考手册”,并阅读相应的部分。
尝试弄清楚ls .*
如何和为什么工作。
对自己说10次:“我会一直使用 verbose 选项。verbose 选项通常用作-v
参数”。
对自己说10次:“我会永远用ls
检查任何危险的命令”。
练习 5:Bash:环境变量,env
,set
,export
原文: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
解释
- 创建变量
foo
,并将Hello World!
这一行放在其中。 - 打印出变量
foo
。 - 打印所有环境变量的列表,它传递给
grep
,打印出只包含变量foo
的行。注意变量foo
存在。 - 打印所有环境变量列表,它们传递给你执行的任何程序。注意变量
foo
不存在。 - 使变量
foo
可用于从当前 shell 执行的所有程序。 - 现在你可以看到,你的变量确实可用于你执行的所有程序。
- 将
ls /
放入变量foo
。 - 执行包含在变量
foo
中的命令。
附加题
输入并执行env
和set
。看看有多少个不同的变量?不用担心,通常你可以通过谷歌搜索,快速了解一个变量的作用。尝试这样做。
尝试输入:
代码语言:javascript复制set | egrep '^[[:alpha:]].*$'
现在,试试set
。看见我在这里做了什么嘛?快速的解释是:
egrep '^[[:alpha:]].*$'
仅仅打印出以字母开头的行,它是每个字母,并忽略其他行。现在不要纠结这个,也不要纠结|
符号。以后我会解释它。
在这里阅读env
和set
之间的区别: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:语言设置,LANG
,locale
,dpkg-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
作为默认的系统区域。
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:~$
解释
- 打印你当前使用的
LANG
变量,程序用它来确定与你进行交互时要使用的语言。 - 按照指定的国家/地区的格式,打印所有区域变量,程序员使用它们来设置数字,地址,电话格式,以及其它。
- 显示 unix 手册系统的手册页。注意我如何使用
#
来注释一个动作,#
之后的所有内容都不执行。 - 执行程序来重新配置你的区域设置。因为这个变化是系统层次的,你需要以 root 身份运行这个命令,这就是在
dpkg-reconfigure locales
前面有sudo
的原因。现在不要纠结sudo
,我会让你熟悉它。 - 导出
LANG
变量,用于设置所有其他区域变量。 - 打印出
LANG
变量,你可以看到它已经改变了,按照你的预期。 - 打印其它已更改的区域变量。
- 以法语显示
man
手册页。 - 将`LANG变量恢复为英文。
附加题
- 阅读区域设置的手册页。为此,请输入
man locale
。 - 现在,阅读
man 7 locale
页面。注意我 在这里使用7
,来调用关于约定的手册页。如果你愿意, 现在阅读man man
,了解其他可能的代码是什么,或者只是等待涵盖它的练习。
练习 7:Bash:重定向,stdin
,stdout
,stderr
,<
,>
,>>
,|
,tee
,pv
原文:Exercise 7. Bash: redirection, stdin, stdout, stderr, <, >, >>, |, tee, pv 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译
在 Linux 中,一切都只是文件。这意味着,对于控制台程序:
- 键盘表示为一个文件,Bash 从中读取你的输入。
- 显示器表示为一个文件,Bash向输出写入它。
让我们假设,你有一个程序可以计算文件中的行。你可以通过键入wc -l
来调用它。现在尝试一下 没有发生什么事吧?它只是卡在那里。错了,它正在等待你的输入。这是它的工作原理:
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:~$
解释
- 在你的系统上安装
pv
(管道查看器)程序,稍后你需要它。 - 将你的输入读取到变量
foo
。这是可能的,因为显示器和键盘实际上是系统的电传打字机。是的,那个电传打字机!在线阅读更多关于tty
的东西。 - 这是你输入的东西。
- 将
foo
变量的内容重定向到foo.out
文件,在进程中创建文件或覆盖现有文件,而不会警告删除所有内容! - 打印出
foo.out
的内容。 - 将
foo
变量的内容重定向到foo.out
文件,在进程中创建文件或附加 到现有文件。这是安全的,但不要混淆这两者,否则你会有巨大的悲剧。 - 再次打印出
foo.out
内容。 - 将空内容重定向到
foo.out
,在进程中清空文件。 - 显示文件确实是空的。
- 列出你的目录并将其通过管道输出到
grep
。它的原理是,获取所有ls -al
的输出,并将其扔给grep
。这又称为管道。 - 将你的目录列出到屏幕上,并写入
ls.out
。很有用! - 创建大小为 10 兆字节的清零文件。现在不要纠结它如何工作。
- 将这个文件读取到
/dev/null
,这是你系统中终极的垃圾桶,什么都没有。写入它的一切都会小时。请注意,pv
会向你展示读取文件的进程,如果你尝试使用其他命令读取它,你就不会知道它需要多长时间来完成。 - 删除
foo.out
。记得自己清理一下。 - 删除
test.img
。
附加题
- 阅读 stackoverflow 上的管道和重定向,再次阅读 stackoverflow 和 Greg 的 Wiki,这是非常有用的资源,记住它。
- 打开 bash 的
man
页面,向下滚动到 REDIRECTION 部分并阅读它。 - 阅读
man pv
和man tee
的描述。