我有时候会在vi中打开只读文件,忘记在打开之前执行chmod +w
。有没有办法在vi内部更改文件?
类似于 !r chmod +w [文件名]
的方式吗?
是否有一种快捷方式可以引用当前打开的文件而无需拼写其长名称?
只需使用
:!chmod +w %
在命令模式下。% 将被替换为当前文件名。如果你有写文件的权限,那么你可以使用感叹号来强制执行:
:w!
如果您没有权限并需要更改用户,但仍然想要写入文件,有时可以尝试以下方法:
:w !sudo tee %
:w !sudo tee %
命令会将文件输入发送到 tee
,然后将其转发到当前文件 %
。 - Lubo Kanev我知道这是一个旧帖子,但在 Vim Version8 中已经包含了一个函数,可以更改文件权限。
根据 version8.txt 文件:
setfperm() 设置文件的权限
然后可以通过Vim中的“call”命令调用此函数。
操作步骤如下:
:call setfperm("file name","permissions")
"权限"字符串的结构与Vim文档中描述的形式相同:
getfperm({fname}) getfperm() 结果是一个字符串,表示给定文件{fname}的读、写和执行权限。如果{fname}不存在或其目录无法读取,则返回空字符串。 结果的形式为“rwxrwxrwx”,其中每组“rwx”标志依次表示文件所有者、所属组和其他用户的权限。 如果用户没有给定的权限,则用字符串“-”替换该标志。例如: :echo getfperm("/etc/passwd") 这将从安全角度(希望如此)显示字符串“rw-r--r--”甚至是“rw-------”。
一个最简示例:
:call setfperm("foo.txt","rwxrwxrwx")
这会在当前目录下的“foo.txt”文件中添加读取、写入和执行权限。
setfperm()
函数也出现在 Vim 7 中(至少,7.4 版本有它)。:call setfperm(expand("%"), "rwxr-xr-x")
是一种设置当前文件模式为 0755 的方式,无需明确输入文件名。 - the paul!chmod +w %
% 表示当前文件名。
你也可以将一个键映射到它,比如 Ctrl-W。
:map <C-w> :!chmod +w %<CR>
<CR>
",您需要按下 Ctrl-V Ctrl-M。w !sudo tee %
然后按“Enter”键。 然后输入
:q!
要成功退出编辑器。
:!chmod <perms> <file>
如果vi仍然不想写它,
:se cpo-=W
如果您很懒,也可以使用vim自带的netrw模块来完成此操作,例如:Texplore
,然后在正常模式下滚动到文件并输入 gp
。 八进制或符号至少有效。
对于多个文件来说,这种方法可能有点棘手,但是对于单个缓冲区窗口而言,可以使用冒号命令历史记录重复命令,会更加直观一些。
function! ChmodPlus(expr, pat)
let file = expand('%')
let oldperms = getfperm(file)
let newperms = substitute(oldperms, a:expr, a:pat, '')
if (oldperms != newperms)
call setfperm(file, newperms)
endif
echom(printf('Permissions: %s', newperms))
endfunction
function! ChmodPlusX()
call ChmodPlus('^\(..\).', '\1x')
endfunction
function! ChmodPlusW()
call ChmodPlus('^\(.\).', '\1w')
endfunction
" Make current file writeable
noremap <silent> <Leader>W :call ChmodPlusW()<CR>
" Make current file executable
noremap <silent> <Leader>X :call ChmodPlusX()<CR>
" autoreload file
set autoread
" chmod +x current file
"
" not using setfperm() here to have the behavior of chmod(1), e.g. adding and
" using the umask.
function! ChmodThis(perm)
if getbufinfo('%')[0].changed
echo "Modified, save first!"
else
call system('chmod ' .. a:perm .. ' -- ' .. expand('%:S'))
echo "chmod done."
endif
endfunction
noremap <silent> <Leader>X :call ChmodThis('+x')<CR>
:Chmod
命令。它完全符合您的要求。 - evanthegrayt