LinuxDown.com
Linux系统下载网——精选每一篇高品质的技术干货
  1. 首页
  2. 开源快讯
  3. 正文

Linux基础知识:软链接文件命令模式总结

2023年3月16日 102点热度

目录

概述

Linux的文件和目录

ln命令

1哪些是软链接文件?

2哪些是硬链接文件?

mv命令

1源和目的在同一个文件系统

2源和目的在不同的文件系统

cp命令

1auto模式

2always模式

3never模式

总结

快捷复制键是哪个_复制图层的快捷键是_linux 复制快捷键

​

 

复制图层的快捷键是_快捷复制键是哪个_linux 复制快捷键

​

概述

Linux下有3种“拷贝”,分别是ln,cplinux 复制快捷键,mv,这3个命令似乎都能copy出一个新的文件下来。

悉心的男子伴看见我给“拷贝”打上了双冒号?由于Linux的这3个命令有极大的区别,毕竟用户看上去是拷贝出了新文件。

你是否当初遇见过以下问题,想通缘由了吗?:

ln创建链接文件,软链接可以跨文件系统,硬链接跨文件系统会报错,为何?;mv似乎有时侯快,有时侯特别慢linux 复制快捷键,有些时侯就会残留垃圾,为何?;cp拷贝数据有时快,有时侯特别慢,源文件和目标文件所占数学空间居然不一致?

本篇文章看完,希望你以上问题不再有疑惑鸟哥的linux私房菜,从容使用ln,mv,cp命令。

温情提示:

以下我们只讨论文件的简单操作,关于目录操作或则复杂参数的操作不在我们本次主题以内,我们忽视;

coreutils库的代码版本用的是8.3;

我们来看下简单的3个命令操作。首先在执行以下命令之前,打算一个不小的test的普通文件(例如1G)。

"拷贝"命令一:ln

快捷复制键是哪个_linux 复制快捷键_复制图层的快捷键是

# 创建一个软链接文件
ln -s ./test ./test_soft_link
# 创建一个硬连接文件
ln ./test ./test_hard_link

你会发觉当前目录出现了两个新文件test_soft_link,test_hard_link。但是你会发觉拷贝速率好快?为何呢?

"拷贝"命令二:mv

把test文件"拷贝"到./backup/目录

mv ./test ./backup/

更神奇的是,似乎copy一个1G的文件,速率也贼快?

“拷贝”命令三:cp

把test文件"拷贝"到./backup/目录

cp ./test ./backup/

前面我们看见,似乎ln,mv,cp这3个命令都是“拷贝”?似乎都进行了数据复制出了新的文件?

答案:其实不是。这3个看上去都是复制出了新文件,但毕竟天壤之别。我们一个个来解密。

在解密这3个命令之前,我们必须先备考文件的基础知识点,Linux的文件和目录的关系。

Linux的文件和目录

在深度分析Linuxcp的秘密一文中,我们详尽分析了文件系统的形态。有几个关键知识点:

文件系统内有3个关键区域:超级块区域,inode区域,数据block区域;其中一个inode和一个文件对应,包含了文件的元数据信息;一个inode有惟一的编号,可以理解成就是单调递增的整数。诸如1,2,3,4,5,6,,,,;

关于里面,我们注意到inode虽然标示的是一个平坦的结构,inode索引到数据data区域,每位inode都有惟一编号。

问题来了:Linux的目录是一个倒挂的树状结构呀,为何里面说inode是平坦的结构?如下:

快捷复制键是哪个_复制图层的快捷键是_linux 复制快捷键

​

Linux的文件确实是树状结构,inode也确实是平坦的结构。你会觉得到由于是由于之前故意忽视了一个几个东西:目录文件和dentry项。这是两个特别重要的概念,我们挨个解释下。

文件系统中虽然有两种文件类型,分为:

可以通过inode->i_mode数组,使用S_ISREG,S_ISDIR这两个宏来判定是那个类型。普通文件很容易理解,就是普通的数据文件,inode上面储存元数据,inode可以索引到block,block上面储存用户的数据。目录文件inode储存元数据,block上面储存的是目录条目。目录条目是哪些样子的东西?

举个形象的事例:在当前testdir目录下,有dir1,dir2,dir3这三个文件。假定dir1的inode编号是1024,dir2是1025,dir3是1026。

这么现实是这样的:

testdir这个目录首先会对应有一个inode,inode->i_mode的类型是目录,但是都会有block块,通过inode->i_blocks能索引到这种block;block上面储存的内容很简单,是一个个目录条目,内核的名子简写为dirent,每一个dirent本质就是一个文件名子到inode编号的映射,所以,testdir这个目录文件的block里存了3条记录[dir1,1024],[dir2,1025],[dir3,1026];

复制图层的快捷键是_linux 复制快捷键_快捷复制键是哪个

​

所以,目录究竟是哪些呢?就储存形态而已,目录也是文件,储存的是名子到inodenumber的映射表。dirent虽然就是directoryentry的简写。

似乎还没提到树状结构?

虽然早已讲了一半了,树状结构的数据结构基础早已有了,就是目录文件和dirent的实现。

假定叶子结点的为普通文件

针对开篇的图,虽然c盘上储存了3个目录文件

linux 复制快捷键_复制图层的快捷键是_快捷复制键是哪个

​

这个时侯,读者同学你是不是都可以用笔划出一个树状结构了,显存的树状结构也是如此来的。通过c盘的映射数据构造下来。在显存中,这个树状结构的节点用dentry来表示(一般翻译成目录项,并且笔者觉得这个翻译很容易让人误会)。

以下是笔者从内核精简下来的dentry结构体,通过这个总结到几个信息:

dentry绑定到惟一一个inode结构体;dentry有父,子,兄弟的索引路径,有这个就足够在显存中建立一个树了,但是事实也确实这么;

struct dentry {
   // ...
   struct dentry  *d_parent;   /* 父节点 */
   struct qstr    d_name;      // 名字
   struct inode   *d_inode;    // inode 结构体
   struct list_head d_child;     /* 兄弟节点 */
   struct list_head d_subdirs;   /* 子节点 */ 
};

所以,见到现今理解了吗?父、子表针,这就是精典的树状结构须要的数组呀。目录文件类型为树状结构提供了储存到c盘持久化的一种形态,是一种map表项的形态,每一个表项我们称作dirent。文件树的结构在显存中以dentry结构体彰显。

划重点:仔细理解下dirent和dentry的概念和形态,仔细理解c盘的数据形态和显存的数据结构形态,前面要考的。

ln命令

ln是Linux的基础命令之一,是link的简写,顾名思义就是跟链接文件相关的一个命令。通常句型如下:

ln [OPTION]... TARGET LINK_NAME

ln可以拿来创建一个链接文件,有趣的是,链接文件有两个不同的类别:

1哪些是软链接文件?

无论是软链接还是硬链接都是“链接”文件,也就是说,通过这个链接文件都能找到背后的那种“源文件”。首先说推论:

所以,你明白了吗?软链接文件就是一个文件而已,文件上面储存的是一个路径字符串。所以软链接文件可以十分灵活,链接文件本身和源前馈,只通过一段路径字符串寻路。

所以,软链接文件是可以跨文件系统创建的。

linux 复制快捷键_快捷复制键是哪个_复制图层的快捷键是

​

有兴趣的男子伴可以去看源码实现,在coreutils库里,调用栈如下:

main -> do_link -> force_symlinkat -> symlinkat

linux 复制快捷键_复制图层的快捷键是_快捷复制键是哪个

也就是说最终调用的是系统调用symlinkat来完成创建,而这个symlinkat系统调用在内核由不同的文件系统实现。举个反例,假如是minix文件系统,这么对应的函数就是minix_symlink。minix_symlink这个函数上来就是新建一个inode,之后在对应的目录文件中添加一个dirent。来来来,我们看一眼minix_symlink的主干代码:

static int minix_symlink(struct inode * dir, struct dentry *dentry,
          const char * symname)
{
 // ...
 // 新建一个 inode,inode 类型为 S_IFLNK 链接类型
 inode = minix_new_inode(dir, S_IFLNK | 0777, &err);
 if (!inode)
   goto out;
 // 填充链接文件内容
 minix_set_inode(inode, 0);
 err = page_symlink(inode, symname, i);
 if (err)
   goto out_fail;
 // 绑定 dentry 和 inode
 err = add_nondir(dentry, inode);
 //...
}

划重点:软链接文件是新建了一个文件,文件类型是链接文件,文件内容就是一段字符串路径。分配新的inode,显存对应新的dentry,其实了,也新增了一个dirent。软链文件可以跨越不同的文件系统。

2哪些是硬链接文件?

如今我们晓得了,软链接文件如何找到源文件的?通过路径找到的,路径就储存在软链接文件中。硬链接文件又如何办到的呢?

硬链接很神奇,硬链接虽然是新建了一个dirent而已。下边是重点:

硬链接文件或许并没有新建文件(也就是说,没有消耗inode和文件所需的block块);硬链接虽然是更改了当前目录所在的目录文件,加了一个dirent而已,这个dirent用一个新的name名子指向原先的inodenumber;

快捷复制键是哪个_linux 复制快捷键_复制图层的快捷键是

​

重点来了,因为新旧两个dirent都是指向同一个inode,这么就造成了一个限制:不能跨文件系统。由于,不同文件系统的inode管理都是独立的。

感兴趣的朋友可以试下,跨文件系统创建硬链接都会报告如下错误:Invalidcross-devicelink

sh-4.4# ln /dev/shm/source.txt ./dest.txt
ln: failed to create hard link './dest.txt' => '/dev/shm/source.txt': Invalid cross-device link

有兴趣的男子伴可以去看源码实现,在coreutils库里,调用栈如下:

main -> do_link -> force_linkat -> linkat

也就是说最终调用的是系统调用linkat来完成创建常用linux系统,而这个linkat系统调用在内核由不同的文件系统实现。举个反例,假如是minix文件系统,这么对应的函数就是minix_link。这个函数从显存上来讲是把一个dentry和inode关联上去。从c盘数据结构上来讲,会在对应目录文件中降低一个dirent项。

划重点:硬链接只降低了一个dirent项,只更改了目录文件而已。不涉及到inode数目的变化。新的name指向原先的inode。

mv命令

mv是move的简写,从疗效上来看,是把源文件搬动到另一个位置。

你是否思索过mv命令内部是如何实现的呢?

是把源文件拷贝到目标位置,之后删掉源文件吗?所以,说mv其实也是“拷贝”?

虽然,并不是,确切的说不完全是。

对于mv的讨论,要拆分成源和目的文件是否在同一个文件系统。

1源和目的在同一个文件系统

mv命令的核心操作是系统调用rename,rename从内核实现来说只涉及到元数据的操作,只涉及到dirent的增删(其实不同的文件系统可能略有不同,并且大致如是)。一般操作是删掉源文件所在目录文件中的dirent,在目标目录文件中添加一个新的dirent项。

划重点:inodenumber不变,inode不变,不增不减,还是原先的inode结构体,所以数据完全没有拷贝。

mv的调用栈如下,感兴趣的可以自己调试。

main -> renameat2
main -> movefile -> do_move -> copy -> copy_internal -> renameat2

我们用事例来直观看下,首先打算好一个source.txt文件,用stat命令看下元数据信息:

sh-4.4# stat source.txt
  File: source.txt
  Size: 0          Blocks: 0          IO Block: 4096   regular empty file
Device: 78h/120d Inode: 3156362     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)

我们看见inode编号是:3156362。之后执行mv命令:

sh-4.4# mv source.txt dest.txt

之后stat看下dest.txt文件的信息:

sh-4.4# stat dest.txt
  File: dest.txt
  Size: 0          Blocks: 0          IO Block: 4096   regular empty file
Device: 78h/120d Inode: 3156362     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)

发觉没?inode编号还是3156362。

2源和目的在不同的文件系统

还记得之前我们提过,因为硬链接是直接在目录文件中添加一个dirent,名子直接指向源文件的inode,不同文件系统都是独立的一套inode管理系统,所以硬链接不能跨文件系统。

这么问题来了,mv遇见跨文件系统的场景呢,如何处理?是否还是rename?

举个反例,如下命令,源和目的是不同的文件系统。我虚拟机的挂载点如下:

sh-4.4# df -h
Filesystem      Size  Used Avail Use% Mounted on
overlay          59G  3.5G   52G   7% /
tmpfs            64M     0   64M   0% /dev
shm              64M     0   64M   0% /dev/shm

我故意选购/home/qiya/testdir和/dev/shm/,这两个目录分别对应了"/"和"/dev/shm/"的挂载点的文件系统,分属两个不同的文件系统。我们先提早看下源文件的信息(主要是inode信息):

sh-4.4# stat /dev/shm/source.txt
  File: /dev/shm/source.txt
  Size: 0          Blocks: 0          IO Block: 4096   regular empty file
Device: 7fh/127d Inode: 163990      Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)

我们执行以下mv命令:

sh-4.4# mv /dev/shm/source.txt /home/qiya/testdir/dest.txt

之后看下目的文件信息:

sh-4.4# stat dest.txt
  File: dest.txt
  Size: 0          Blocks: 0          IO Block: 4096   regular empty file
Device: 78h/120d Inode: 3155414     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)

对比有没有发觉,inode的信息是不一样的,inodenumber是不一样的(是不是跟前面同一文件系统下的mv现象不一致)哪些缘由呢?我下边一一道来,从原理出分析。

当系统调用rename的时侯,假如源和目的不在同一文件系统时,会报告EXDEV的错误码,提示该调用不能跨文件系统。

#define EXDEV           18      /* Cross-device link */

所以,rename是不能用于跨文件系统的,这个时侯如何办?

划重点:这个时侯操作分成两步走,先copy,后remove。

第一步:走不了rename,这么就退化成copy,也就是真正的拷贝。读取源文件,写入目标位置,生成一个全新的目标文件副本;这儿调用的copy_reg的函数封装(要晓得这个函数是cp命令的核心函数,在深度分析Linuxcp的秘密有深入探讨过);ln,mv,cp是在coreutils库里的命令,公用函数本身就是可以复用的;第二步:删掉源文件,使用rm函数删掉;

思索问题:mv跨文件系统的时侯,假如第一步成功了,第二步失败了(例如没有删掉权限)会如何样?

会造成垃圾。也就是说,目标处创建了一个新文件,源文件并没有删掉。这个小实验有兴趣的可以试下。

cp命令

cp命令才是真正的数据拷贝命令,即拷贝元数据,也会拷贝数据。cp命令也是我之前花了万字篇幅剖析的命令,详尽可见:深度分析Linuxcp的秘密。这儿就不再赘言,下边提炼出关于拷贝的3种模式。

涉及到数据拷贝的,关键有个--sparse参数,可以控制拷贝数据的IO次数。

1auto模式

重点:跳过文件空洞。是cp默认的模式

cp src.txt dest.txt

​

2always模式

重点:跳过文件空洞,就会跳过全0数据,是空间最省的模式。

cp --sparse=always src.txt dest.txt

​

3never模式

重点:无脑拷贝,从头拷贝到尾,不辨识化学空洞和全0数据,是速率最慢的一种模式。

cp --sparse=never src.txt dest.txt

​

复用之前画的这3张图,很形象的彰显了cp的行为。

总结

目录文件是一种特殊的文件,可以理解成储存的是dirent列表。dirent只是名子到inode的映射,这个是树状结构的基础;常说目录树在显存中确实是一个树的结构,每位节点由dentry结构体表示;ln-s创建软链接文件,软链接文件是一个独立的新文件,有一个新的inode,有新的dentry,文件类型为link,文件内容就是一条指向源的路径,所以软链的创建可以无视文件系统,跨越山河;ln默认创建硬联接,硬链接文件只在目录文件里添加了一个新dirent项,文件inode还是和原文件同一个,所以硬链接不能跨文件系统(由于不同的文件系统是独立的一套inode管理方法,不同的文件系统实例对inodenumber的解释各有不同);ln命令其实创建出了新文件,但毕竟不然,ln只跟元数据相关,涉及到dirent的变动,不涉及到数据的拷贝,起不到数据备份的目的;mv虽然是调用rename调用,在同一个文件系统中不涉及到数据拷贝,只涉及到元数据变更(dirent的增删),所以速率也很快。但若果mv的源和目的在不同的文件系统,这么都会退化成真正的copy,会涉及到数据拷贝,这个时侯速率相对慢一些,慢成哪些样子?就跟cp命令一样;cp命令才是真正的数据拷贝命令,速率可能相对慢一些,而且cp命令有--spare可以优化拷贝速率,针对空洞和全0数据,可以跳过,因而针对稀疏文件可以节约大量c盘IO;

​

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: linux系统 命令模式 拷贝 文件目录 软链接
最后更新:2023年3月16日

Linux系统下载网

每日更新,欢迎收藏♥ 不积跬步无以至千里,加油,共勉。

点赞
< 上一篇
下一篇 >

文章评论

您需要 登录 之后才可以评论

Linux系统下载网

每日更新,欢迎收藏♥
不积跬步无以至千里,加油,共勉。

最新 热点 随机
最新 热点 随机
掌握Linux内核链接脚本:详解、实践与优化 文本编辑器Vim有个内置功能很强加密功能 Linux安装MySQL5.6:详细步骤及下载地址 字符集1.计算机的存储规则(ASCII)计算机解码规则 linux goldendict Linux黄金词典:英语学习高效利器 Linux中解压缩zip文件乱码怎么办?如何解决问题? Linux轻松搭建网站:安装Apache服务攻略 Linux操作系统多数Intemet设备内核移植过程及方法 轻松安装CentOS,EasyBCD教程上手 Windows端完全转入了Linux服务器端,语言也彻底变成C Golang开发者乱码问题的原因及解决方法设置中解析 企业Linux安全运维:10大分析实战经验 轻松搞定CentOS本地域名解析与静态IP设置 Linux命令用于显示内存使用情况的free(-bkmotV) Linux必备:64位Tomcat下载安装教程 精通Linux设备驱动开发,掌握9大关键技巧! Linux下MySQL下载安装教程,快速学会MySQL安装! 升级到7.10完成后执行一下sudo-getclean释放空间 玩转Linux C索引:3.1版本安装指南 轻松掌握Linux启动应用程序命令,提高工作效率
RedHat虚拟机网络配置:9大详细分析,让你轻松上手掌握Linux内核链接脚本:详解、实践与优化Linux虚拟机必备:轻松安装VMwareTools网络安装Linux系统:多种方法全解析高效、易用的Linux笔记整理下载工具关于嵌入式Linux操作系统的原理和实现的详细分析Linux发行版在开机启动时拉起的服务进程中如何关闭?Linux内核通信方式详细解析:探讨八种实现方法CentOS如何安装中文输入法,让Linux操作系统更方便?有个发行版居然模仿起了Win11系统,还内置安卓虚拟机深入了解Linux内核开发,掌握基本技巧!Linux登录认证失败的8个问题,让你不再孤单一个如何记录ssh命令操作的小技巧-OpenSSH命令Linux轻松安装:VirtualBox虚拟机指南Fedora 25轻松安装智能fcitx输入法Linux系统在启动过程中都加载了哪些内容?Linux系统连接服务器:从入门到精通的技巧!Linux安装内核开发包及编译器,轻松开发!学习linux内核是需要一步一步内核的一些建议吧!Linux操作系统进程内核文件的设置文件是什么
下载宏碁中文Linux系统,畅享特色功能 win11系统好不好用win11的新功能,权衡是否升级到win11 centos mysql 5.6 安装 CentOS安装MySQL 5.6,详细教程不容错过!-苏州安嘉 图片版pdf转换成word文字怎么给文件添加密码 轻松安装Linux Deepin:U盘启动教程 跑OracleLinux+Database11g还是可以吗? 轻松掌握!linux查看内网ip的必备命令 linuxlinux有哪些版本?linux有什么版本 高效编译内核,轻松上手嵌入式Linux驱动开发pdf 学会这些,让你轻松将Fedora安装到U盘 轻松查询Linux系统32位或64位,快速搞定! linux reuse Linux系统代码复用技巧,提高工作效率 零开始介绍Linux环境变量路径相关的知识 嵌入式Linux应用开发和Linux开发的编程技巧和底层开发 cdcserial驱动是一款可以解决电脑连接手机时提示缺少cdc 掌握Linux发行版本查看技巧,轻松了解系统信息 嵌入式Linux要如何学习内核原理?150多G Linux发行版在开机启动时拉起的服务进程中如何关闭? 深度探秘Linux内核:文件系统与设备驱动架构设计 Linux虚拟机使用教程:安装、配置、实战详解
标签聚合
虚拟机 软件 sudo linux社区 linux服务器 文件目录 u盘启动 centos linux系统 电脑
书籍
课程
技术群
技术干货大合集↓
  • 2023年3月 / 249篇
友情链接:

Linux书籍 | Linux命令 | Linux系统 | RHCE红帽认证 | Linux软件 | Linux教程 | CentOS系统 | Linux内核 | Linux服务器 | Linux大神 | IT资源

COPYRIGHT © 2023 LinuxDown.com ALL RIGHTS RESERVED.

京ICP备14023444号-2