日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux 普通用户退出vim,Linux环境下VI/VIM编辑文件时无权限保存的解决方法(普通用户)...

發布時間:2025/5/22 linux 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux 普通用户退出vim,Linux环境下VI/VIM编辑文件时无权限保存的解决方法(普通用户)... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在Linux環境下,如果直接使用VI/VIM命令編輯沒有修改權限的文件時,保存的時候就會提示用戶無法進行保存操作,一般的解決方法只能是關閉文件重新以sudo權限打開該文件編輯后再保存(前提是用戶具有sudo權限)。其實,在VI/VIM模式下通過一些簡單的命令,就能在不關閉當前文件的情況下達到保存文件的目的。

方法一

關于%! sudo tee % > /dev/null這條命令的說明如下

此命令是把當前文件(即%)作為stdin傳給sudo tee命令來執行。

方法二

在Linux上工作的朋友很可能遇到過這樣一種情況,當你用Vim編輯完一個文件時,運行:wq保存退出,突然蹦出一個錯誤:

E45: 'readonly' option is set (add ! to override)

這表明文件是只讀的,按照提示,加上!強制保存::w!,結果又一個錯誤出現:

"readonly-file-name" E212: Can't open file for writing

文件明明存在,為何提示無法打開?這錯誤又代表什么呢?查看文檔:help E212:

For some reason the file you are writing to cannot be created or overwritten.

The reason could be that you do not have permission to write in the directory

or the file name is not valid.

原來是可能沒有權限造成的。此時你才想起,這個文件需要root權限才能編輯,而當前登陸的只是普通用戶,在編輯之前你忘了使用sudo來啟動Vim,所以才保存失敗。于是為了防止修改丟失,你只好先把它保存為另外一個臨時文件temp-file-name,然后退出Vim,再運行sudo mv temp-file-name readonly-file-name覆蓋原文件。

但這樣操作過于繁瑣。而且如果只是想暫存此文件,還需要接著修改,則希望保留Vim的工作狀態,比如編輯歷史,buffer狀態等等,該怎么辦?能不能在不退出Vim的情況下獲得root權限來保存這個文件?

解決方案

答案是可以,執行這樣一條命令即可:

:w !sudo tee %

接下來我們來分析這個命令為什么可以工作。首先查看文檔:help :w,向下滾動一點可以看到:

*:w_c* *:write_c*

:[range]w[rite] [++opt] !{cmd}

Execute {cmd} with [range] lines as standard input

(note the space in front of the '!'). {cmd} is

executed like with ":!{cmd}", any '!' is replaced with

the previous command |:!|.

The default [range] for the ":w" command is the whole buffer (1,$)

把這個使用方法對應前面的命令,如下所示:

: w !sudo tee %

| | | |

:[range]w[rite] [++opt] !{cmd}

我們并未指定range,參見幫助文檔最下面一行,當range未指定時,默認情況下是整個文件。此外,這里也沒有指定opt。

Vim中執行外部命令

接下來是一個嘆號!,它表示其后面部分是外部命令,即sudo tee %。文檔中說的很清楚,這和直接執行:!{cmd}是一樣的效果。后者的作用是打開shell執行一個命令,比如,運行:!ls,會顯示當前工作目錄下的所有文件,這非常有用,任何可以在shell中執行的命令都可以在不退出Vim的情況下運行,并且可以將結果讀入到Vim中來。試想,如果你要在Vim中插入當前工作路徑或者當前工作路徑下的所有文件名,你可以運行:

:r !pwd或:r !ls

此時所有的內容便被讀入至Vim,而不需要退出Vim,執行命令,然后拷貝粘貼至Vim中。有了它,Vim可以自由的操作shell而無需退出。

命令的另一種表示形式

再看前面的文檔:

Execute {cmd} with [range] lines as standard input

所以實際上這個:w并未真的保存當前文件,就像執行:w new-file-name時,它將當前文件的內容保存到另外一個new-file-name的文件中,在這里它相當于一個另存為,而不是保存。它將當前文檔的內容寫到后面cmd的標準輸入中,再來執行cmd,所以整個命令可以轉換為一個具有相同功能的普通shell命令:

$ cat readonly-file-name | sudo tee %

這樣看起來”正常”些了。其中sudo很好理解,意為切換至root執行后面的命令,tee和%是什么呢?

%的意義

我們先來看%,執行:help cmdline-special可以看到:

In Ex commands, at places where a file name can be used, the following

characters have a special meaning. These can also be used in the expression

function expand() |expand()|.

% Is replaced with the current file name. *:_%* *c_%*

在執行外部命令時,%會擴展成當前文件名,所以上述的cmd也就成了sudo tee readonly-file-name。此時整個命令即:

$ cat readonly-file-name | sudo tee readonly-file-name

注意:在另外一個地方我們也經常用到%,沒錯,替換。但是那里%的作用不一樣,執行:help :%查看文檔:

Line numbers may be specified with: *:range* *E14* *{address}*

{number} an absolute line number

...

% equal to 1,$ (the entire file) *:%*

在替換中,%的意義是代表整個文件,而不是文件名。所以對于命令:%s/old/new/g,它表示的是替換整篇文檔中的old為new,而不是把文件名中的old換成new。

tee的作用

現在只剩一個難點: tee。它究竟有何用?維基百科上對其有一個詳細的解釋,你也可以查看man page。下面這幅圖很形象的展示了tee是如何工作的:

ls -l的輸出經過管道傳給了tee,后者做了兩件事,首先拷貝一份數據到文件file.txt,同時再拷貝一份到其標準輸出。數據再次經過管道傳給less的標準輸入,所以它在不影響原有管道的基礎上對數據作了一份拷貝并保存到文件中。看上圖中間部分,它很像大寫的字母T,給數據流動增加了一個分支,tee的名字也由此而來。

現在上面的命令就容易理解了,tee將其標準輸入中的內容寫到了readonly-file-name中,從而達到了更新只讀文件的目的。當然這里其實還有另外一半數據:tee的標準輸出,但因為后面沒有跟其它的命令,所以這份輸出相當于被拋棄。當然也可以在后面補上>?/dev/null,以顯式的丟棄標準輸出,但是這對整個操作沒有影響,而且會增加輸入的字符數,因此只需上述命令即可。

命令執行之后

運行完上述命令后,會出現下面的提示:

W12: Warning: File "readonly-file-name" has changed and the buffer was changed in Vim as well

See ":help W12" for more info.

[O]K, (L)oad File:

Vim提示文件更新,詢問是確認還是重新加載文件。建議直接輸入O,因為這樣可以保留Vim的工作狀態,比如編輯歷史,buffer等,撤消等操作仍然可以繼續。而如果選擇L,文件會以全新的文件打開,所有的工作狀態便丟失了,此時無法執行撤消,buffer中的內容也被清空。

更簡單的方案:映射

上述方式非常完美的解決了文章開始提出的問題,但畢竟命令還是有些長,為了避免每次輸入一長串的命令,可以將它映射為一個簡單的命令加到.vimrc中:

" Allow saving of files as sudo when I forgot to start vim using sudo.

cmap w!! w !sudo tee > /dev/null %

這樣,簡單的運行:w!!即可。命令后半部分> /dev/null在前面已經解釋過,作用為顯式的丟掉標準輸出的內容。

另一種思路

至此,一個比較完美但很tricky的方案已經完成。你可能會問,為什么不用下面這樣更常見的命令呢?這不是更容易理解,更簡單一些么?

:w !sudo cat > %

重定向的問題

我們來分析一遍,像前面一樣,它可以被轉換為相同功能的shell命令:

$ cat readonly-file-name | sudo cat > %

這條命令看起來一點問題沒有,可一旦運行,又會出現另外一個錯誤:

/bin/sh: readonly-file-name: Permission denied

shell returned 1

這是怎么回事?不是明明加了sudo么,為什么還提示說沒有權限?稍安勿躁,原因在于重定向,它是由shell執行的,在一切命令開始之前,shell便會執行重定向操作,所以重定向并未受sudo影響,而當前的shell本身也是以普通用戶身份啟動,也沒有權限寫此文件,因此便有了上面的錯誤。

重定向方案

這里介紹了幾種解決重定向無權限錯誤的方法,當然除了tee方案以外,還有一種比較方便的方案:以sudo打開一個shell,然后在該具有root權限的shell中執行含重定向的命令,如:

:w !sudo sh -c 'cat > %'

可是這樣執行時,由于單引號的存在,所以在Vim中%并不會展開,它被原封不動的傳給了shell,而在shell中,一個單獨的%相當于nil,所以文件被重定向到了nil,所有內容丟失,保存文件失敗。

既然是由于%沒有展開導致的錯誤,那么試著將單引號'換成雙引號"再試一次:

:w !sudo sh -c "cat > %"

成功!這是因為在將命令傳到shell去之前,%已經被擴展為當前的文件名。有關單引號和雙引號的區別可以參考這里,簡單的說就是單引號會將其內部的內容原封不動的傳給命令,但是雙引號會展開一些內容,比如變量,轉義字符等。

當然,也可以像前面一樣將它映射為一個簡單的命令并添加到.vimrc中:

" Allow saving of files as sudo when I forgot to start vim using sudo.

cmap w!! w !sudo sh -c "cat > %"

注意:這里不再需要把輸出重定向到/dev/null中。

寫在結尾

至此,借助Vim強大的靈活性,實現了兩種方案,可以在以普通用戶啟動的Vim中保存需root權限的文件。兩者的原理類似,都是利用了Vim可以執行外部命令這一特性,區別在于使用不同的shell命令。如果你還有其它的方案,歡迎給我留言。

(全文完)

feihu

2014.07.30 于 Shenzhen

總結

以上是生活随笔為你收集整理的linux 普通用户退出vim,Linux环境下VI/VIM编辑文件时无权限保存的解决方法(普通用户)...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 91视频综合网 | 亚洲成人h | 亚洲一卡二卡 | 日韩欧美无| 国产成人免费看 | 国产日韩欧美中文 | 青青色在线视频 | 黄色特级毛片 | 日本污网站| 蜜臀av性久久久久蜜臀aⅴ四虎 | 校园sm主奴调教1v1罚视频 | 六月婷婷七月丁香 | 一区二区三区四区精品 | 黄色国产一区 | 999视频| 少妇高潮灌满白浆毛片免费看 | 黄色av网站在线看 | 色九九| 国产精品乱轮 | 久久影视 | 丰满熟女人妻一区二区三区 | 免费国偷自产拍精品视频 | 偷操 | 国产操人 | 久久国色 | 神马午夜不卡 | 国产三级短视频 | 欧洲国产精品 | 99国内揄拍国内精品人妻免费 | 久久久久亚洲av片无码 | 医生强烈淫药h调教小说视频 | 99久久精品国产成人一区二区 | 91网在线播放 | 国产精品一区二三区 | 在线观看免费观看在线 | 免费黄色网址视频 | 欧洲精品无码一区二区 | www天堂在线 | 欧美 日韩 成人 | 深喉口爆一区二区三区 | 少妇人妻好深好紧精品无码 | 日本精品一区二区在线观看 | 久久精品999 | 亚洲天堂av女优 | 四虎影库永久在线 | 午夜视频在线免费 | 中文一级片 | 91视频高清 | 欧美成人做爰大片免费看黄石 | 久久精品欧美 | 国产一级黄色电影 | 国产一区成人 | 久久99精品久久久久子伦 | 久热免费在线视频 | 国内免费毛片 | 香蕉网在线视频 | 欧美三级韩国三级日本三斤在线观看 | 四虎影视精品 | 五月深爱 | 久久五月综合 | 国产精品欧美综合亚洲 | 一本色道综合久久欧美日韩精品 | 久色视频在线播放 | 国产乱人| 久久久久国色av免费观看性色 | 国产久操视频 | 精品福利电影 | 粉嫩av一区二区白浆 | 激情黄色小说网站 | 在线v| jizz高潮| 欧美日韩八区 | 久久蜜桃精品 | 国产又粗又大又爽 | 国产良妇出轨视频在线观看 | 天天插综合网 | 日韩中文一区二区 | 国内精品卡一卡二卡三 | 亚洲v在线观看 | 岛国av免费 | 欧美三级黄色大片 | 欧美一级大黄 | 韩日免费视频 | 香蕉视频在线观看www | 精品无码黑人又粗又大又长 | 国偷自产av一区二区三区麻豆 | 善良的女朋友在线观看 | 国产污在线观看 | 性一交一乱一透一a级 | 国产成人精品女人久久久 | 成人免费黄色小视频 | 日韩综合色 | 亚洲色图清纯唯美 | 免费在线一级片 | 国产亚洲二区 | 欧美在线观看视频一区二区 | 国产大片在线观看 | 欧日韩一区二区三区 | 97自拍视频 |