Linux深入探索13-目录操作

----- 最近更新【2022-01-22】-----

本文目录结构预览:

  • 一、相关概念
    1、绝对路径与相对路径
    2、当前目录
    3、Home 目录
    4、路径名缩写:.、..与~
  • 二、相关命令
    1、切换与查看工作目录:cd、pwd
    2、目录操作:创建(mkdir)、移除(rmdir)、重命名(mv)
    3、目录栈:dirs、pushd、popd
    4、显示目录相关内容:ls
    5、检查文件类型:file
    6、显示目录树:tree
  • 三、参考

一、相关概念

1、绝对路径与相对路径

将 Unix 文件系统想象成一棵大树,树干就是根目录,其它目录都是树枝。

路径名或者路径通过列举由/分隔开的目录序列描述文件树中的一个位置。如果目录序列从根目录/开始,则称之为 绝对路径名(absolute pathname)。如果目录序列从工作目录开始,则称之为 相对路径名(relative pathname)。

2、当前目录

Unix 允许在某一时刻指定一个目录作为工作目录(也称为当前目录)。

使用命令 pwd 可查看当前工作目录:

[nosee@instance-4 ~/mygit]$ pwd
/home/nosee/mygit

3、Home 目录

在 Unix 中每个实际的用户都会根据用户标识被赋予一个 home 目录,用户登录系统默认就处于用户目录当中。

使用命令cd可从任何目录切换回 home 目录:

[nosee@instance-4 ~/mygit]$ cd
[nosee@instance-4 ~]$ 

使用命令echo $HOME可查看 home 目录名称:

[nosee@instance-4 ~]$ echo $HOME
/home/nosee

4、路径名缩写:...~

1)在路径名中,.(点号)也用于表示当前目录,..(两个点)表示上级目录。
2)多次使用..可以向上移动多个层次,如../../
3)...都是缩写,实际上指的是一个完整的路径名。
4)在有些情况,必须指定绝对路径,这时可以使用.缩写来表示工作目录的名称。
5)~表示当前用户的 home 目录
6)当需要引用别的用户标识的 home 目录时,可使用:~用户标识
7)~是 shell 提供的一个抽象概念,是为了方便引用 home 目录而提供的,它与...的实现方式并不相同。

二、相关命令

1、切换与查看工作目录:cd、pwd

1)cd
cd - 更改当前工作目录(Change the shell working directory)
语法:cd [-L|[-P [-e]] [-@]] [dir]

如果在输入命令时,使用-代替目录名称,那么cd将切换回上一个目录(上一次访问的目录)。

常用选项:
-P,如果该目录是符号链接则跳转到实际的路径名下。

例:

[nosee@instance-4 /proc]$ cd
[nosee@instance-4 ~]$ cd -
/proc
[nosee@instance-4 /proc]$ 

2)pwd
pwd - 显示当前工作目录(print working directory)

[nosee@instance-4 ~]$ pwd
/home/nosee

2、目录操作:创建(mkdir)、移除(rmdir)、重命名(mv)

1)mkdir - 创建新目录
make directories.
语法:mkdir [OPTION]... directory...

其中 directory 是希望创建的目录名称。当指定要创建的目录名称时,既可以使用绝对路径名,也可以使用相对路径名,同时还可以使用标准缩写。

例:

[nosee@instance-4 ~/test]$ mkdir dd1 ./dd2 ~/test/dd3 $HOME/test/dd4 /home/nosee/test/dd5
[nosee@instance-4 ~/test]$ ls -alF
total 28
drwxr-xr-x  7 nosee nosee 4096 Jan 20 02:28 ./
drwxr-xr-x 12 nosee nosee 4096 Jan 20 02:27 ../
drwxr-xr-x  2 nosee nosee 4096 Jan 20 02:28 dd1/
drwxr-xr-x  2 nosee nosee 4096 Jan 20 02:28 dd2/
drwxr-xr-x  2 nosee nosee 4096 Jan 20 02:28 dd3/
drwxr-xr-x  2 nosee nosee 4096 Jan 20 02:28 dd4/
drwxr-xr-x  2 nosee nosee 4096 Jan 20 02:28 dd5/

在创建目录时,要遵循 Unix 制定的两条合理规则:第一,在一个目录中不能创建相同名字的子目录;第二,如果父目录不存在则不能创建子目录。

例:可以在同一条命令中按顺序创建父目录和子目录,注意,父目录一定要在子目录前面

[nosee@instance-4 ~/test]$ mkdir dd6 dd6/aaa dd6/bbb dd6/ccc

常用选项:

  • -p(make parent 创建父目录)当父目录不存在时将自动创建父目录。

例:

[nosee@instance-4 ~/test]$ mkdir dd7/a1
mkdir: cannot create directory ‘dd7/a1’: No such file or directory
[nosee@instance-4 ~/test]$ mkdir -p dd7/a1
[nosee@instance-4 ~/test]$ ll dd7
total 12
drwxr-xr-x 3 nosee nosee 4096 Jan 20 02:41 .
drwxr-xr-x 9 nosee nosee 4096 Jan 20 02:41 ..
drwxr-xr-x 2 nosee nosee 4096 Jan 20 02:41 a1

2)rmdir - 移除目录
移除空目录。(remove empty directories)
语法:rmdir [OPTION]... directory...

例:移除目录 dd1、dd2、dd3、dd4、dd5,这些都是空目录(里面不包含子目录或文件)。

[nosee@instance-4 ~/test]$ ls -lF
total 28
drwxr-xr-x 2 nosee nosee 4096 Jan 20 02:50 dd1/
drwxr-xr-x 2 nosee nosee 4096 Jan 20 02:50 dd2/
drwxr-xr-x 2 nosee nosee 4096 Jan 20 02:50 dd3/
drwxr-xr-x 2 nosee nosee 4096 Jan 20 02:50 dd4/
drwxr-xr-x 2 nosee nosee 4096 Jan 20 02:50 dd5/
drwxr-xr-x 5 nosee nosee 4096 Jan 20 02:35 dd6/
drwxr-xr-x 3 nosee nosee 4096 Jan 20 02:41 dd7/
[nosee@instance-4 ~/test]$ rmdir dd[1-5]
[nosee@instance-4 ~/test]$ ls -lF
total 8
drwxr-xr-x 5 nosee nosee 4096 Jan 20 02:35 dd6/
drwxr-xr-x 3 nosee nosee 4096 Jan 20 02:41 dd7/

当移除目录时,要遵循 Unix 制定的两条规则:第一,不能移除非空的目录(如果一个目录中含有子目录或者文件,那么这个目录就不是空的);第二,不能删除工作目录和根目录之间的任何目录。

注:如果当前工作目录是空的,那么移除工作目录是允许的,但一般不这样做。

常用选项:

  • -p,(delete parent 删除父目录)自动移除所有需要移除的父目录。

例:如下的rmdir -p a/b/c相当于rmdir a/b/c a/b a

[nosee@instance-4 ~/test]$ ls -lF
total 0
[nosee@instance-4 ~/test]$ mkdir -p a/b/c
[nosee@instance-4 ~/test]$ ls -lF
total 4
drwxr-xr-x 3 nosee nosee 4096 Jan 20 03:25 a/
[nosee@instance-4 ~/test]$ rmdir -p a/b/c/
[nosee@instance-4 ~/test]$ ls -lF
total 0

注:如果确实是需要删除非空的目录,可以使用rm -r命令,将移除所有子目录及其内容。

3)mv - 重命名(移动)目录
使用 mv 程序可以将目录从一个位置“移动”到另一个位置,如果新位置和原来在同一个目录中,那么实际结果就是对原始目录重命名。当 mv 移动目录时,同时移动目录中的所有文件和子目录。
mv - move (rename) files.

语法:mv [OPTION]... [-T] SOURCE DEST
mv [OPTION]... SOURCE... DIRECTORY
mv [OPTION]... -t DIRECTORY SOURCE...

例:

[nosee@instance-4 ~/test]$ ls -lF
total 4
drwxr-xr-x 3 nosee nosee 4096 Jan 20 19:05 doc/
[nosee@instance-4 ~/test]$ mv doc/  text
[nosee@instance-4 ~/test]$ ls -lF
total 4
drwxr-xr-x 3 nosee nosee 4096 Jan 20 19:05 text/

如果目录已经存在,那么 mv 将原始目录移动到目标目录中去,如:

[nosee@instance-4 ~/test]$ mkdir mydoc
[nosee@instance-4 ~/test]$ ls -lF
total 8
drwxr-xr-x 2 nosee nosee 4096 Jan 20 19:08 mydoc/
drwxr-xr-x 3 nosee nosee 4096 Jan 20 19:05 text/
[nosee@instance-4 ~/test]$ mv text/ mydoc/
[nosee@instance-4 ~/test]$ ls -lF
total 4
drwxr-xr-x 3 nosee nosee 4096 Jan 20 19:09 mydoc/
[nosee@instance-4 ~/test]$ ls -lF mydoc/
total 4
drwxr-xr-x 3 nosee nosee 4096 Jan 20 19:05 text/

如果目标目录目录已经存在,并且目标目录里面也有了同名子目录,那将移动失败。如:

[nosee@instance-4 ~/test]$ mkdir text
[nosee@instance-4 ~/test]$ mv text/ mydoc/
mv: cannot move 'text/' to 'mydoc/text': Directory not empty

mv 程序可作用于目录,但也可以作用于文件。在我的下一篇文件《Linux深入探索14-文件操作》中还会详细说明。

3、目录栈:dirs、pushd、popd

栈是一种后进先出的数据结构。在 shell 中有几个内置命令,可以把 Linux 的目录类似于栈的结构来处理。(注:内置命令可使用help 内置命令man bash来查看内置命令的使用说明)

命令介绍:
dirs - 查看目录栈。(Display directory stack)
pushd - 向目录栈压入一个目录。(Add directories to stack)
popd - 从目录栈弹出一个目录。(Remove directories from stack)
命令语法:
dirs [-clpv] [+N] [-N]
pushd [-n] [+N | -N | dir]
popd [-n] [+N | -N]

常用说明:

命令 说明
dirs 显示名称:home 目录显示为~
dirs -l 显示名称:home 目录显示为完整路径名
dirs -v 显示名称:每个一行,并有数字标识
pushd directory 改变工作目录:将 directory 压入到栈中
pushd +n 改变工作目录:将目录 #n 移到栈顶
popd 改变工作目录:弹出栈顶
popd +n 从栈中移除目录 #n
dirs -c 除当前工作目录外,移除栈中的全部目录

例(注意 shell 提示符里面的工作目录的变化):

[nosee@instance-4 ~]$ dirs -v
 0  ~
[nosee@instance-4 ~]$ pushd /etc
/etc ~
[nosee@instance-4 /etc]$ pushd /var
/var /etc ~
[nosee@instance-4 /var]$ pushd /usr
/usr /var /etc ~
[nosee@instance-4 /usr]$ pushd /lib
/lib /usr /var /etc ~
[nosee@instance-4 /lib]$ dirs -v
 0  /lib
 1  /usr
 2  /var
 3  /etc
 4  ~
[nosee@instance-4 /lib]$ dirs -l
/lib /usr /var /etc /home/nosee
[nosee@instance-4 /lib]$ pushd +3
/etc ~ /lib /usr /var
[nosee@instance-4 /etc]$ dirs -v
 0  /etc
 1  ~
 2  /lib
 3  /usr
 4  /var
[nosee@instance-4 /etc]$ popd 
~ /lib /usr /var
[nosee@instance-4 ~]$ dirs -v
 0  ~
 1  /lib
 2  /usr
 3  /var
[nosee@instance-4 ~]$ popd +1
~ /usr /var
[nosee@instance-4 ~]$ dirs -c
[nosee@instance-4 ~]$ dirs -v
 0  ~

注:
1)在任何时候,栈顶存放的就是工作目录的名称。
2)当dirs使用选项时,选项必须单独指定。(如,可以使用dirs -l -v,但不能使用dirs -lv
3)当使用pushd +n移动目录时,看上去就像整个目录栈从 #n 的位置向上移动,#n 前面的目录依次转到了栈的底部。
4)大多时候,在目录间的移动我们使用命令cd就够了,但有时只是在几个固定的目录间来回切换,此时使用目录栈也是不错的体验。
5)目录栈的使用原理,其实也有点类似于 shell 命令的历史列表。

4、显示目录相关内容:ls

ls - 默认情况按字母表顺序显示目录中各文件的名称。(list directory contents)

1)语法
ls [OPTION]... [FILE]...

常用选项:

  • -a,(all files)显示所有全部文件(默认情况下 ls 不显示隐藏文件,即.字符开头的文件)
  • -C,强制以列的形式输出(如写入到文件或管道线中)
  • -d,(directory)将目录按文件进行显示,不查看目录的内部。
  • -F,附加上文件类型的标志,如:*/=>@|
  • -h,(human-readable)以人类可读的方式显示出文件大小的单位(kb),一般结合-s-l一起使用
  • -i,(小写i)显示文件的 i 节点
  • -l,(小写L)每个一行的形式显示(列举)文件详细信息
  • -r,以相反的顺序显示文件名
  • -R,(recursive 递归)列举目录中的所有直接或间接的子目录和文件,即显示整个目录树的信息
  • -s,(size)在每个文件名前面以 KB 为单位列出文件的大小
  • -t,按时间的顺序显示文件(最新到最旧)
  • --color[=WHEN],使用颜色区别文件的类型

2)类型标志 -F、-l
使用-F选项,以下类型标志会附加到文件名的后面:

标志 含义
普通文件:非执行文件
* 普通文件:可执行文件
/ 目录
@ 符号链接
| 命名管道

3)选项-l
使用-l选项,在每个文件对应行的最前面会有如下指示符:

指示符 含义
- 普通文件
d 目录
l 符号连接
b 特殊文件(块设备)
c 特殊文件(字符设备)
p 命名管道/FIFO
[nosee@instance-4 ~/test]$ ls -lF
total 4
drwxr-xr-x 3 nosee nosee 4096 Jan 20 19:05 doc/

注:
如上面drwxr-xr-x中的d就表示目录。
文件名左边的时间和日期为文件的最后修改时间。

4)关于文件大小

在文本文件中,一个字节可以存放一个字符(ASCII 字符)。但在 Linux 中,文件所使用的磁盘空间的数量不同于文件中数据的数量。

如:新建一个只有一个字符的文本文件

[nosee@instance-4 ~]$ cat > a
a
^C
[nosee@instance-4 ~]$ ls -lsh a
4.0K -rw-r--r-- 1 nosee nosee 2 Jan 21 13:18 a

从上面例子可以看到,文件a包含了2个字节(B)大小的数据,但是文件占用了4KB的存储空间大小。

这是因为,在文件系统中,空间以固定大小的组块进行分配,我们将固定大小的组块称为(block)。根据文件系统的不同,块的大小有 521B、1KB、2KB 或 4KB 等。为文件分配的最小磁盘空间就是一个块,就算一个仅包含 1 字节的文件也要占据一个块。

注意:
目录前面的大小指的是目录本身的大小,而不是目录内容的大小。
实际上,目录只包含有文件的名称及文件的 i 节点号。因此,目录的内容相当小:只有一列名称,每个名称对应一个 i 节点号。

5)--color
--color选项说明:
很多 linux 会默认在配置文件中设置:alias ls='ls --color=auto'

使用颜色区别不同的文件类型,以下命令是等价的:

ls --color
ls --color=always
ls --color=yes
ls --color=force

关闭颜色使用:

ls --color=never
ls --color=no
ls --color=none

通常,创建颜色的特殊代码混杂在输出中。当在显示器上输出时,这不会有什么问题。但是当将输出发送给管道或文件时,信息可能会有点乱。为了避免这样,可以通过将--color设备为auto,告诉 ls 命令仅当输出要在终端上显示时才使用颜色。以下命令也是等价的:

ls --color=auto
ls --color=tty
ls --color=if-tty

使用如ls --color=yes | less命令,则可以发现这些颜色的特殊代码:

letter.txt
ESC[0mESC[01;34mmygitESC[0m
ESC[01;31mmysql-apt-config_0.8.20-1_all.debESC[0m
pr_info.txt
sorttest
ESC[01;34mtestESC[0m
uuu.txt
ESC[01;34mwwwESC[0m

注:关于颜色的配置信息,可以通过查看环境变量LS_COKORS或使用命令dircolors查看。如果想自己定制颜色,可以使用具体的dircolors命令生成一条设置LS_COKORS的命令,然后在初始配置文件中使用这条命令。

6)通配符
当使用ls命令后面需要指定一个模糊的文件名或目录名时,可以通过使用特定的元字符——通配符。

注意:在这里,这些通配符的含义和正则表达式里面的是有一定差别的。

符号 含义
* 匹配 0 个或多个任意字符(除/,因为这个是路径名中的定界符)
? 匹配任何 1 个字符(注:不是 0 或 1 个)
[list] 匹配 list 中任何 1 个字符
[^list] 匹配不在 list 中的任何 1 个字符
[n-m] 匹配指定字符范围中的 1 个字符,如[a-z]、[0-9]
{string1|string2} 匹配其中 1 个指定的字符串
{string1,string2} 依次匹配大括号中的字符串

注:如果匹配到的是一个目录,则相当于ls 目录,会展开该目录。

7)案例说明

例1:默认情况

[nosee@instance-4 ~]$ ls /
bin   dev  home  lib32  libx32      media  opt   root  sbin  sys  usr
boot  etc  lib   lib64  lost+found  mnt    proc  run   srv   tmp  var

注意,默认情况下,文件以列的形式按字母顺序排序。也就是说,要竖着阅读文件,而不是横着读。

但是,当将 ls 的输出重定向到文件或者管道线时,ls 以每个文件占一行的形式输出结果。如:

[nosee@instance-4 ~]$ ls / | wc -l
22

例2:显示指定目录下的整个目录树

[nosee@instance-4 ~/test]$ ls -R
.:
A  Z  a  mydoc  z

./mydoc:
haha.txt  text

./mydoc/text:
a

./mydoc/text/a:
b

./mydoc/text/a/b:

5、检查文件类型:file

file - 确定文件类型。(determine file type)

虽然使用ls查看目录时也可以同时查看到文件的简单类型,但是使用file命令则可以得到更加详细的文件类型。

1)常见案例
例:

[nosee@instance-4 ~]$ file www
www: directory
[nosee@instance-4 ~]$ file uuu.txt 
uuu.txt: ASCII text
[nosee@instance-4 ~]$ file sorttest 
sorttest: UTF-8 Unicode text
[nosee@instance-4 ~]$ file mysql-apt-config_0.8.20-1_all.deb 
mysql-apt-config_0.8.20-1_all.deb: Debian binary package (format 2.0)
[nosee@instance-4 ~]$ file /bin
/bin: symbolic link to usr/bin

多个文件同时查看:

[nosee@instance-4 ~]$ file www uuu.txt sorttest mysql-apt-config_0.8.20-1_all.deb /bin
www:                               directory
uuu.txt:                           ASCII text
sorttest:                          UTF-8 Unicode text
mysql-apt-config_0.8.20-1_all.deb: Debian binary package (format 2.0)
/bin:                              symbolic link to usr/bin

查看指定目录中的全部文件:

[nosee@instance-4 ~]$ file www/*
www/hi.php:                 PHP script, ASCII text
www/index.html:             UTF-8 Unicode text
www/mygit-site:             directory
www/mysql_connect_test.php: PHP script, UTF-8 Unicode text
www/phpinfo.php:            PHP script, UTF-8 Unicode text
www/thinkphp-1:             directory
www/thinkphp-2:             directory
www/thinkphp-3:             directory
www/thinkphp-4:             directory

2)查看可执行文件
当查看一个可执行文件时,则会得到更长的信息(一般是供程序员和系统管理员查看)。
如(因为输出太长了,可以使用命令foldfmt格式化输出):

[nosee@instance-4 /usr/bin]$ file ls
ls: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=a65f86cd6394e8f583c14d786d13b3bcbe051b87, stripped
[nosee@instance-4 /usr/bin]$ file ls | fold
ls: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked,
 interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=a65
f86cd6394e8f583c14d786d13b3bcbe051b87, stripped

可执行文件信息解释:
ELF:可执行和链接格式(Executable and Linking Format),可执行文件的标准格式。
64-bit:字长。
LSB:采用最低有效字节(Least Significant Byte)词序编译,x86 处理器使用。
executable:可执行文件。
version 1 (SYSV):内部文件格式的版本。
dynamically linked:使用共享库,而不是静态链接。
GNU/Linux 3.2.0:编译程序的操作系统和内核版本。
stripped:将符号表移除的可执行文件(缩减可执行文件大小)。

6、显示目录树:tree

Linux 中有一个功能强大的工具 tree ,可以绘制文件系统任何部分的图形。(有些系统默认并没有安装该程序,这时需要手动安装sudo apt-get install tree

tree - list contents of directories in a tree-like format

例:默认没有带任何选项的tree

[10:12 @nosee ~]$ tree
.
├── Desktop
│   └── test1
├── Documents
├── Downloads
├── Music
├── Pictures
├── Public
├── snap
│   └── snap-store
│       ├── 518
│       ├── 558
│       ├── common
│       └── current -> 558
├── Templates
├── Videos
└── 桌面
    ├── my_host
    └── 新建文本文档.txt

15 directories, 3 files

tree 程序有许多选项,其中有几个选项是和 ls 命令中的同名选项是一样的意思。如:-a-s-F-r-t
其它常用选项:

  • -d,只显示目录
  • -f,显示完整的路径名
  • -i,输出结果时省略缩进
  • -L level,指定树的深度,level 为一个数字
  • -l,(小写L)跟随所有符号链接

三、参考

书箱:《Unix & Linux 大学教程》第二十四章 (美)Harley Hahn 著 张杰良 译

上一篇:linux 下python2升级python3 ---NEW


下一篇:13.深入理解static(类变量),而非static修饰属于对象变量