美文网首页Linux终极玩家
Linux深入探索13-目录操作

Linux深入探索13-目录操作

作者: 四月不见 | 来源:发表于2022-01-21 23:01 被阅读0次

    ----- 最近更新【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深入探索13-目录操作

        本文链接:https://www.haomeiwen.com/subject/viadhrtx.html