接上一篇博客,这次要说的这四个命令ls,cp,mv,ln可真的是超高使用率,不管是谁,大神还是小神还是菜鸡,凡是Linux操作系统的使用者,让他排出心目中的使用率最高的命令,必定有这几个命令。

我这么吹这几个命令是不是有点言过其实呢?其实不然,Linux操作系统有句名言是:一切皆是文件(跑个题,Java号称一切皆是对象,好像事情突然变得有点意思了吧~~~),而这几个命令是针对文件的,分别是,列出文件,拷贝文件,移动文件,建立链接文件。

下面就开始介绍这几个超高使用率的命令啦~~~~~~!!

一,ls命令

工欲善其事必先利其器,同样的,查看文件是能够合理使用各类文件的前提喽,ls命令就是这么的朴实无华-----显示当前目录或者指定目录下的所有文件以及子目录。

首先呢,应该了解一下Linux系统下都有些什么类型的文件。

文件,英文是file,在Linux中文件的类型有软硬链接文件,设备文件,普通文本文件,目录文件,管道文件这么五种类型。

这些文件构成了Linux操作系统,而我们查看文件也就是使用ls命令主要的功能第一,能够知道是什么类型的文件(这样可以大概知道这个文件有什么大体的用处),第二,能够知道文件的属性(我更倾向于属性等于三维),能知道如何合理的使用这些文件,第三,通过文件的属性,能够知道哪些是我们需要的文件,哪些是应该丢弃的文件。从而提高系统的安全,保护我们的操作系统。

(1)初识ls命令

[root@hdp-1 ~]# stat /usr/bin/ls
File: ‘/usr/bin/ls’
Size: 117608 Blocks: 232 IO Block: 4096 regular file
Device: fd00h/64768d Inode: 201345636 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2021-09-10 00:09:00.600000430 +0800
Modify: 2019-08-20 14:25:31.000000000 +0800
Change: 2021-07-07 04:05:56.092000596 +0800
Birth: -
[root@hdp-1 ~]# file !$
file /usr/bin/ls
/usr/bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=aaf05615b6c91d3cbb076af81aeff531c5d7dfd9, stripped
[root@hdp-1 ~]# ls -al /usr/bin/ls
-rwxr-xr-x. 1 root root 117608 Aug 20 2019 /usr/bin/ls

以上,我使用了stat和file命令查看了ls命令,倒数第三行表示,这个ls命令是一个可执行的二进制程序,并且是一个内嵌在操作系统内的符合GNU标准的程序。当然,根据Modify: 2019-08-20 14:25:31.000000000 +0800 可以合理推断出这个操作系统发布时间是2019年8月20号,还有我写这一段内容的时候大概是在2021年9月10号凌晨左右(好像暴露了作息时间哦~~~~,其实是上次的关机时间啦)

(2)ls命令的使用方式

ls命令通常需要搭配各种各样的参数,如果仅仅是单独的ls命令,并不能得到太多有用的信息,最为常用的参数是 -ailh 以及长参数--lcontext和短参数 -Z(selinux专属参数,极少用)

例如下面的例子,使用了常用的4个参数 -ailh

[root@hdp-1 ~]# ls -alhi
total 15M
69 dr-xr-x---. 5 root root 4.0K Sep 10 00:40 .
64 dr-xr-xr-x. 17 root root 244 Jul 6 20:19 ..
1176457 -rw-------. 1 root root 1.7K Sep 10 00:34 .bash_history
607271 -rw-r--r--. 1 root root 18 Dec 29 2013 .bash_logout
607272 -rw-r--r--. 1 root root 176 Dec 29 2013 .bash_profile
607273 -rw-r--r--. 1 root root 176 Dec 29 2013 .bashrc
1176464 -rw-r--r-- 1 root root 1.8K Aug 20 00:58 config.inc.php
1177322 -rw-r--r-- 1 root root 338 Sep 8 23:40 stop.sh
607275 -rw-r--r--. 1 root root 129 Dec 29 2013 .tcshrc
1177311 -rw-r--r-- 1 root root 14 Aug 31 22:45 user
1177307 -rw------- 1 root root 4.9K Sep 9 00:19 .viminfo

-a 参数 表示显示所有文件和文件夹,包括隐藏文件(夹)

-i参数 表示打印显示文件的inode号(这个inode号是十分重要的,区分两个文件是否为硬链接的哦)

-l参数 表示详尽模式输出打印

-h参数 以人类可理解的方式显示文件的大小,比如,文件是小于1M的,那么就显示多少多少k,如果文件小于1G,那么就显示多少多少M

-Z 打印文件的selinux相关上下文,等价于-lcontext,此参数极少用,因为一般selinux都是关闭的状态,了解即可。

注意一下输出里的这个:

69 dr-xr-x---.  5 root root 4.0K Sep 10 00:40 .
64 dr-xr-xr-x. 17 root root 244 Jul 6 20:19 ..

第一行表示该路径下有5-2个文件夹,第二行表示此路径的上级目录有17-1个文件夹,(当前路径是root目录,root目录的上一级目录是/目录。一个.是减2,两个. 是减1),大家可以多进一些目录,发现其中的规律。

总的来说,ls命令还是可以十分方便的查看文件,可以看到文件的创建时间,修改时间,最后访问时间,文件的属组,文件的大小,文件的权限,文件的类型等等十分重要的信息。

二,cp命令

cp命令主要的参数是 -i -r -f -a

cp -i  cp命令覆盖文件总是提示要输入yes或no,即使加上-f参数也无法强行覆盖

cp -a 复制时保持源文件的权限属性,不做任何改变,通常是多用户时使用

cp -r 迭代复制文件夹以及文件夹内的子文件夹和子文件

cp -f 强制复制,即使源文件和目标文件相同

cp命令的作用是:复制一份和源文件一致的文件到目标路径下,并且兼具改名功能,因此,通常用作备份配置文件。

cp命令比较特殊,复制,移动,删除三个命令出于安全考虑,本身是不会在源文件覆盖目标相同文件的时候提示交互的,毕竟Linux系统是由文件构成的嘛,但现在的Linux发行版默认在每个用户下的环境变量中配置了如下内容(cp -i  会在源文件与目标文件相同时交互的询问是否覆盖目标文件):

# .bashrc

# User specific aliases and functions

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'

# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi

也可以看成加强了cp -i,通俗的说就是一直都有cp命令的交互---复制文件并覆盖目标文件的相同文件时询问是否覆盖(rm和mv都是如此)。 

Linux发行版这么做本意是好的,毕竟复制操作有时候也是危险的,但某些时候,比如更新大量数据文件的时候,并不希望源文件覆盖目标文件的时候一直提示交互(比如,a文件夹及其下的所有内容移动到b文件夹下,a就叫源,b就叫目标文件夹),让你确认是否覆盖目标文件,成千上万个文件都要回车的话,是会让人崩溃的。

因此,有两种方式来解决这一问题,

1,一劳永逸的方法

修改环境配置文件,通常是在 ~/.bashrc这个文件中,比如,上面的示例,将相关alias的行删除或者注释,然后重新source ~/.bashrc即可不在提示交互直接覆盖。

2,临时生效

每次cp的命令前加转义符 \包裹cp命令即可,比如,有a文件夹和b文件夹,a下有很多子文件夹和子文件,b同样有很多子文件夹和子文件,并且有一部分子文件夹和子文件是相同的,那么,cp 命令应该为   \cp a/* b/

三,mv命令

mv命令是移动命令,等价于这么一个动作:复制源文件到目标路径下,然后删除源文件。可以看出,mv命令比cp命令多出了一个删除源文件的动作,因此,也是具有更改文件名的功能。

但需要注意,不能仅仅将mv当成升级版的cp命令,因为 mv移动文件夹不需要迭代,并且,mv 文件夹a/* 文件夹b/ 和mv 文件夹a  文件夹b/  两种是有细微差别的。现予以举例说明:

比如,我现在有一个docker二进制安装包,解压后得到一个名字为docker的文件夹,ls命令查看一下该文件夹,输出如下:

[root@master ~]# ls -alh docker/
total 191M
drwxrwxr-x 2 1000 1000 138 May 15 2020 .
dr-xr-x---. 21 root root 4.0K Sep 11 10:30 ..
-rwxr-xr-x 1 1000 1000 32M May 15 2020 containerd
-rwxr-xr-x 1 1000 1000 5.8M May 15 2020 containerd-shim
-rwxr-xr-x 1 1000 1000 18M May 15 2020 ctr
-rwxr-xr-x 1 1000 1000 59M May 15 2020 docker
-rwxr-xr-x 1 1000 1000 66M May 15 2020 dockerd
-rwxr-xr-x 1 1000 1000 693K May 15 2020 docker-init
-rwxr-xr-x 1 1000 1000 2.8M May 15 2020 docker-proxy
-rwxr-xr-x 1 1000 1000 9.2M May 15 2020 runc

那么,现在执行命令[root@master ~]# mv docker/* /mnt/  将该文件夹移动到mnt目录下,会是什么情况呢?

可以看到,docker文件夹予以保留了,但现在是一个空文件夹,mnt目录下有如下文件了:

[root@master ~]# ls -al /mnt/
total 195504
drwxr-xr-x. 3 root root 151 Sep 11 10:53 .
dr-xr-xr-x. 17 root root 244 Jun 27 11:24 ..
drwxr-xr-x. 2 root root 6 Jun 27 11:07 cdrom
-rwxr-xr-x 1 1000 1000 32751272 May 15 2020 containerd
-rwxr-xr-x 1 1000 1000 6012928 May 15 2020 containerd-shim
-rwxr-xr-x 1 1000 1000 18194536 May 15 2020 ctr
-rwxr-xr-x 1 1000 1000 61113382 May 15 2020 docker
-rwxr-xr-x 1 1000 1000 68874208 May 15 2020 dockerd
-rwxr-xr-x 1 1000 1000 708616 May 15 2020 docker-init
-rwxr-xr-x 1 1000 1000 2928514 May 15 2020 docker-proxy
-rwxr-xr-x 1 1000 1000 9600696 May 15 2020 runc

那么,[root@master ~]# mv docker /mnt/ 结果是当前目录下没有docker这个文件夹了,mnt目录下有这个文件夹了,并且进入这个文件夹文件也都在。

mv命令实际工作中主要是 -f参数常用,也就是目标有和源相同的文件不提示覆盖,强制移动。

四,ln命令

ln是建立链接的文件,链接分为软链接和硬链接,

软链接相当于Windows的快捷方式,也就是具有快捷方式的所有特性。ln -sf 源文件 链接文件

硬链接相当于完美克隆,硬链接的文件和源文件有着相同的inode号。ln 源文件 链接文件

[root@master ~]# ls -alh rm*
-rwxr-xr-x. 2 root root 62K Nov 6 2016 rm
lrwxrwxrwx 1 root root 2 Sep 11 17:29 rms -> rm

如上所示,输出的第二列表示这个文件是一个硬链接(通常,如果是硬链接的话,第二列会是非1,第二行第一列的l表示rms这个文件是一个软链接文件,链接的是当前目录的rm文件) 

(1)

软链接是ln -sf 绝对路径/源文件(夹)绝对路径/目标文件(夹),如果不指定目标文件(夹)名,那么将使用源的文件(夹)名

软链接基本没有限制,并且删除目标链接后并不会对目标文件(夹)有任何影响。软链接的使用范围基本是在system管理的启动文件,各种动态链接库之间使用,比如,libstdc++.so.6 这样的文件。

一个正确的链接文件我们ls的时候应该显示为绿色的,如果红色,表示此链接是无效的。比如,前面的例子,/mnt目录下的docker文件夹,如果我要将它软链接到/opt目录下,应该如何做呢?

Linux重度使用命令详解(科普ls,cp,mv,ln命令)二_linux

以上,我是进入mnt目录,然后以相对路径链接的,那么,这个链接是无效的,也就是说,软链接的源文件(夹)和目标文件(夹)都需要写绝对路径,链接完成后,以ls命令查看,如果飘红,证明链接失败,如果为绿色的,链接是正常的,成功的。正确的软链接方式应该是这样的:

Linux重度使用命令详解(科普ls,cp,mv,ln命令)二_docker_02

(2)硬链接

ln命令不带参数就是硬链接啦, 硬链接只有两个致命的限制----源文件和目标文件必须在同一个分区,比如,文件a在/dev/sda1 硬链接到b,b文件只能在/dev/sda1内。第二,硬链接只能链接文件,不像软链接可以链接文件也可以链接文件夹。

比如,如果硬链接文件夹的话会报错如下:

[root@master mnt]# ln /mnt/   /opt/
ln: ‘/mnt/’: hard link not allowed for directory

硬链接的作用为保护主要的文件(留存备份),可以快速的设置命令别名,比如,rm命令:

[root@master ~]# ln /usr/bin/rm /usr/bin/myrm
[root@master ~]# mv /usr/bin/rm ~/
[root@master ~]# whereis rm
rm: /usr/share/man/man1/rm.1.gz /usr/share/man/man1p/rm.1p.gz
[root@master ~]# touch test.sh
[root@master ~]# myrm test.sh

以上表示,给原来的rm命令做了一个硬链接,然后将rm命令移出系统环境变量,以后要想在删除文件,就得使用命令myrm这个命令啦。