0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

用vim编辑文件,增加内容不能成功的原因分析

阿铭linux 2018-02-02 15:29 次阅读

大家先了解一些背景知识:

1) 给文件增加了i权限,那文件不能被更改,不能删除,也不能修改名字以及权限。

2) 给文件增加a权限,文件可以追加内容,不能删除,不能修改内容,不能修改名字以及权限。

3) vim一个文件,如果不正常退出,再次编辑时是会提示一些信息的,并且有一个隐藏的文件.xxx.swp

了解以上知识后,再来看下面的现象:

1) 如果给一个文件增加a权限,用vim编辑文件,增加内容(注意是在文件末尾增加内容,不要修改其他内容),并不会成功。

2) 如果给一个目录增加i权限或者a权限,在该目录下面vim一个文件,更改文件内容可以正常保存。

既然a权限可以追加内容,那为何vim一个文件在末尾增加内容不能成功?既然i权限不能修改,那为何在目录里面变更文件内容却可以成功?

关于这两点,你有没有疑惑?下面我们来分析原因。

先不管i或者a权限,

在一个没有i或者a权限的目录下,编辑一个没有i或者a权限的文件,

用strace来查看其执行过程。

mkdir /tmp/test

strace vim /tmp/test/aminglinux.txt 2>/tmp/vim.log

写入一个数字1,然后保存退出。再来查看vim.log的内容。

less /tmp/vim.log

大部分内容你不用关心,只需要看这几行:

stat("/tmp/test/aminglinux.txt", 0x7fff072ecb10) = -1 ENOENT (No such file or directory)

access("/tmp/test/aminglinux.txt", W_OK) = -1 ENOENT (No such file or directory)

open("/tmp/test/aminglinux.txt", O_RDONLY) = -1 ENOENT (No such file or directory)

readlink("/tmp/test/aminglinux.txt", 0x7fff072eb360, 4095) = -1 ENOENT (No such file or directory)

open("/tmp/test/.aminglinux.txt.swp", O_RDONLY) = -1 ENOENT (No such file or directory)

open("/tmp/test/.aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL, 0600) = 3

open("/tmp/test/.aminglinux.txt.swx", O_RDONLY) = -1 ENOENT (No such file or directory)

open("/tmp/test/.aminglinux.txt.swx", O_RDWR|O_CREAT|O_EXCL, 0600) = 4

unlink("/tmp/test/.aminglinux.txt.swx") = 0

unlink("/tmp/test/.aminglinux.txt.swp") = 0

stat("/tmp/test/.aminglinux.txt.swp", 0x7fff072ec310) = -1 ENOENT (No such file or directory)

lstat("/tmp/test/.aminglinux.txt.swp", 0x7fff072ec3e0) = -1 ENOENT (No such file or directory)

lstat("/tmp/test/.aminglinux.txt.swp", 0x7fff072ec8a0) = -1 ENOENT (No such file or directory)

open("/tmp/test/.aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, 0600) = 3

stat("/tmp/test/aminglinux.txt", 0x7fff072eac40) = -1 ENOENT (No such file or directory)

stat("/tmp/test/aminglinux.txt", 0x7fff072ebe20) = -1 ENOENT (No such file or directory)

stat("/tmp/test/aminglinux.txt", 0x7fff072eadf0) = -1 ENOENT (No such file or directory)

write(1, ""/tmp/test/aminglinux.txt"", 26) = 26

stat("/tmp/test/aminglinux.txt", 0x7fff072ec050) = -1 ENOENT (No such file or directory)

open("/tmp/test/aminglinux.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4

stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=2, ...}) = 0

stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=2, ...}) = 0

unlink("/tmp/test/.aminglinux.txt.swp") = 0

看起来乱乱的,其实大概的过程就是vim /tmp/test/aminglinux.txt时,先看有没有.aminglinux.txt.swp以及.aminglinux.txt.swx,因为这两个文件就是vim产生的临时文件,swp先产生,如果swp存在就产生第二个swx。写入的内容先存到swp里,当保存退出vim时,再把swp的内容存到aminglinux.txt里,最后删除掉swp文件。

有了这个认识之后,我们再来分析上面提到的现象1。如果文件给了a权限,那么在编辑该文件时,会产生swp文件,当保存退出时,swp文件内容会写入该文件,这相当于更改该文件,很线上a权限是不允许的。

再来分析现象2,按照我们的推测,如果目录给了a权限,增加文件没问题,也就是说产生swp或者swx文件没有问题,当然把swp或者swx内容写入到文件里时也不会有问题,但swp或者swx文件却不会被删除了,所以再次编辑文件时就会提示临时文件已经存在了。但这并不会影响修改文件内容。

如果给目录设置了i权限的话,vim编辑文件,要产生swp或swx肯定会出错啊,但为何依然能正常编辑文件? 下面继续用strace来分析一下。

chattr +i /tmp/test

strace vim /tmp/test/aminglinux.txt 2> /tmp/vim.log

看vim.log里面和aminglinux.txt相关的信息

stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0

stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0

stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0

stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0

access("/tmp/test/aminglinux.txt", W_OK) = 0

open("/tmp/test/aminglinux.txt", O_RDONLY) = 3

readlink("/tmp/test/aminglinux.txt", 0x7fff49efc6f0, 4095) = -1 EINVAL (Invalid argument)

open("/tmp/test/.aminglinux.txt.swp", O_RDONLY) = -1 ENOENT (No such file or directory)

open("/tmp/test/.aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL, 0600) = -1 EACCES (Permission denied)

stat("/tmp/test/.aminglinux.txt.swp", 0x7fff49efd6a0) = -1 ENOENT (No such file or directory)

lstat("/tmp/test/.aminglinux.txt.swp", 0x7fff49efd770) = -1 ENOENT (No such file or directory)

lstat("/tmp/test/.aminglinux.txt.swp", 0x7fff49efdc30) = -1 ENOENT (No such file or directory)

open("/tmp/test/.aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, 0600) = -1 EACCES (Permission denied)

readlink("/tmp/test/aminglinux.txt", 0x7fff49efc6f0, 4095) = -1 EINVAL (Invalid argument)

open("/root/tmp/aminglinux.txt.swp", O_RDONLY) = -1 ENOTDIR (Not a directory)

open("/root/tmp/aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL, 0600) = -1 ENOTDIR (Not a directory)

stat("/root/tmp/aminglinux.txt.swp", 0x7fff49efd6a0) = -1 ENOTDIR (Not a directory)

lstat("/root/tmp/aminglinux.txt.swp", 0x7fff49efd770) = -1 ENOTDIR (Not a directory)

lstat("/root/tmp/aminglinux.txt.swp", 0x7fff49efdc30) = -1 ENOTDIR (Not a directory)

open("/root/tmp/aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, 0600) = -1 ENOTDIR (Not a directory)

readlink("/tmp/test/aminglinux.txt", 0x7fff49efc6f0, 4095) = -1 EINVAL (Invalid argument)

open("/var/tmp/aminglinux.txt.swp", O_RDONLY) = -1 ENOENT (No such file or directory)

open("/var/tmp/aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL, 0600) = 4

open("/var/tmp/aminglinux.txt.swx", O_RDONLY) = -1 ENOENT (No such file or directory)

open("/var/tmp/aminglinux.txt.swx", O_RDWR|O_CREAT|O_EXCL, 0600) = 5

unlink("/var/tmp/aminglinux.txt.swx") = 0

unlink("/var/tmp/aminglinux.txt.swp") = 0

stat("/var/tmp/aminglinux.txt.swp", 0x7fff49efd6a0) = -1 ENOENT (No such file or directory)

lstat("/var/tmp/aminglinux.txt.swp", 0x7fff49efd770) = -1 ENOENT (No such file or directory)

lstat("/var/tmp/aminglinux.txt.swp", 0x7fff49efdc30) = -1 ENOENT (No such file or directory)

open("/var/tmp/aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, 0600) = 4

chmod("/var/tmp/aminglinux.txt.swp", 0644) = 0

open("/tmp/test/aminglinux.txt", O_RDONLY) = 3

stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0

stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0

stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0

access("/tmp/test/aminglinux.txt", W_OK) = 0

write(1, ""aminglinux.txt"", 16) = 16

stat("aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0

access("aminglinux.txt", W_OK) = 0

getxattr("aminglinux.txt", "system.posix_acl_access", 0x7fff49efd050, 132) = -1 ENODATA (No data available)

stat("aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0

open("aminglinux.txt", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 3

chmod("aminglinux.txt", 0100644) = 0

setxattr("aminglinux.txt", "system.posix_acl_access", "x02x00x00x00x01x00x06x00xffxffxffxffx04x00x04x00xffxffxffxff x00x04x00xffxffxffxff", 28, 0) = 0

stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=6, ...}) = 0

unlink("/var/tmp/aminglinux.txt.swp") = 0

我相信你可以看到Permission denied的提示,这是因为当前目录有i权限,不能增加文件,也就不能在当前目录下生成临时文件。当然,vim如果遇到这样的问题,它还是会“曲线救国”的,于是先找/root/tmp/,但是并没有该目录,只好继续找/var/tmp/,这个目录存在,所以就在这个目录里生成了临时文件(并不是隐藏的)。后面的操作就不用多说了。

既然vim可以在/var/tmp/下生成临时文件,自然也可以在已经设置了i权限的目录里编辑文件的,这样现象2也解释通了。上面罗嗦了这么多,其实我就想表达如下观点:

vim编辑文件时,会在该文件所在目录生成临时隐藏文件.swp和.swx,如果那目录不可写就会到/root/tmp/下或者/var/tmp/下生成临时文件(非隐藏),当编辑的文件保存后,临时文件删除。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    87

    文章

    10990

    浏览量

    206734
  • VIM
    VIM
    +关注

    关注

    0

    文章

    129

    浏览量

    15180

原文标题:你所不知道的vim小秘密

文章出处:【微信号:aming_linux,微信公众号:阿铭linux】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    12个超实用的vim编辑技巧

    vim 是一个很好用的编辑器,应用十分广泛。但关于 vim,总有一些你不知道的事情,我们需要持续不断的学习。
    发表于 11-25 09:26 754次阅读

    汇编中调用c函数中的子函数不能成功点灯

    ), 内容如下。 我在汇编start.S中, 直接调用 bl led_on, 则可以成功点灯, 但如果通过 bl test_led 间接调用led_on, 谮不能成功点灯, 请问是什么原因
    发表于 03-04 04:23

    Ubuntu 1404 Vim编辑文件的操作方法

    Ubuntu 1404 Vim编辑文件的一般操作
    发表于 06-18 10:49

    DSP端的程序就不能成功启动是什么原因

    )",1,但是我将ARM中的工程OMAPL138DemoInterrupt的输出格式改为"eabi(ELF)"后,在重新合成新的ais文件,烧写到NandFlash中,此时DSP端的程序就不能成功启动了,请问是什么原因呢?
    发表于 08-14 10:32

    VIM编辑器使用教程

    8节 VIM编辑器使用教程 主要内容: 1、VIM基本三种模式 2、vim配置文件零基础学嵌入式
    发表于 12-22 06:22

    OKMX6UL编译QT5.12总是不能成功原因?怎么解决?

    现在项目需要 web engine .官方的QT 5.6 又没有 web engine 。所以想编译下QT5.12已经好几天了。都没弄出来。官方的手册说得不太清楚OKMX6UL 编译QT5.12 总是不能成功。有人成功编译过吗
    发表于 01-11 07:15

    VIM编辑器学习

     Vim是一个类似于Vi的文本编辑器,不过在Vi的基础上增加了很多新的特性,Vim普遍被推崇为类Vi编辑器中最好的一个,事实上真正的劲敌来自
    发表于 08-11 16:58 931次阅读

    如何在Vim/Vi编辑器中复制、剪切和粘贴

    使用vim编辑文本文件时,复制,剪切和粘贴文本是最常执行的任务之一。Vim或早期版本Vi已预装在macOS和所有Linux发行版。
    的头像 发表于 12-09 16:54 1w次阅读

    你会使用 Linux 编辑vim 吗?

    vim:是一款编辑器,只负责写代码;相当于 windows 的记事本;
    的头像 发表于 05-10 18:21 540次阅读
    你会使用 Linux <b class='flag-5'>编辑</b>器 <b class='flag-5'>vim</b> 吗?

    vim编辑器的三种模式分别是什么

    Vim编辑器具有三种模式,分别是: 命令模式(Command Mode):这是Vim的默认模式,也是启动后的初始模式。在该模式下,用户不能直接编辑
    的头像 发表于 11-26 15:37 3142次阅读

    linux怎样进入vim编辑模式

    在Linux中,要进入Vim编辑器的编辑模式,可以按照以下步骤进行操作: 打开终端或命令行界面。 输入以下命令来启动Vim编辑器:
    的头像 发表于 11-26 15:43 1754次阅读

    linux怎么执行vim编辑的程序

    在Linux中,你可以通过以下步骤执行Vim编辑器中编写的程序: 打开终端或命令行界面。 使用Vim编辑器打开你的程序文件。假设你的程序
    的头像 发表于 11-26 15:45 520次阅读

    linux怎么保存退出vim

    命令,即可打开vim编辑器。 进入编辑模式:打开vim后,默认是进入了命令模式,此时需要切换到编辑模式。可以通过按下 i 键或 Inser
    的头像 发表于 11-27 14:19 3590次阅读

    linux使用vim新建并编辑文件

    在Linux系统下,Vim是一款功能强大的文本编辑器。它可以用于新建并编辑文件,具有很多高级功能和快捷键。下面是关于如何在Linux上使用Vim
    的头像 发表于 11-28 15:17 1020次阅读

    linux怎么执行vim编辑的程序

    vim 命令,后面加上要编辑文件名。例如, vim test.txt 将打开一个名为test.txt的文件。如果
    的头像 发表于 11-28 15:23 370次阅读