亚洲国产爱久久全部精品_日韩有码在线播放_国产欧美在线观看_中文字幕不卡在线观看

Linux環(huán)境下VI/VIM編輯文件時(shí)無(wú)權(quán)限保存的解決方法(普通用戶)

在Linux環(huán)境下,如果直接使用VI/VIM命令編輯沒有修改權(quán)限的文件時(shí),保存的時(shí)候就會(huì)提示用戶無(wú)法進(jìn)行保存操作,一般的解決方法只能是關(guān)閉文件重新以sudo權(quán)限打開該文件編輯后再保存(前提是用戶具有sudo權(quán)限)。愛掏網(wǎng) - it200.com其實(shí),在VI/VIM模式下通過(guò)一些簡(jiǎn)單的命令,就能在不關(guān)閉當(dāng)前文件的情況下達(dá)到保存文件的目的。愛掏網(wǎng) - it200.com

方法一

關(guān)于%! sudo tee % > /dev/null這條命令的說(shuō)明如下

此命令是把當(dāng)前文件(即%)作為stdin傳給sudo tee命令來(lái)執(zhí)行。愛掏網(wǎng) - it200.com

方法二
 

在Linux上工作的朋友很可能遇到過(guò)這樣一種情況,當(dāng)你用Vim編輯完一個(gè)文件時(shí),運(yùn)行:wq保存退出,突然蹦出一個(gè)錯(cuò)誤:

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

這表明文件是只讀的,按照提示,加上!強(qiáng)制保存::w!,結(jié)果又一個(gè)錯(cuò)誤出現(xiàn):

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

文件明明存在,為何提示無(wú)法打開?這錯(cuò)誤又代表什么呢?查看文檔: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.

原來(lái)是可能沒有權(quán)限造成的。愛掏網(wǎng) - it200.com此時(shí)你才想起,這個(gè)文件需要root權(quán)限才能編輯,而當(dāng)前登陸的只是普通用戶,在編輯之前你忘了使用sudo來(lái)啟動(dòng)Vim,所以才保存失敗。愛掏網(wǎng) - it200.com于是為了防止修改丟失,你只好先把它保存為另外一個(gè)臨時(shí)文件temp-file-name,然后退出Vim,再運(yùn)行sudo mv temp-file-name readonly-file-name覆蓋原文件。愛掏網(wǎng) - it200.com

但這樣操作過(guò)于繁瑣。愛掏網(wǎng) - it200.com而且如果只是想暫存此文件,還需要接著修改,則希望保留Vim的工作狀態(tài),比如編輯歷史,buffer狀態(tài)等等,該怎么辦?能不能在不退出Vim的情況下獲得root權(quán)限來(lái)保存這個(gè)文件?

解決方案

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

:w !sudo tee %

接下來(lái)我們來(lái)分析這個(gè)命令為什么可以工作。愛掏網(wǎng) - it200.com首先查看文檔:help :w,向下滾動(dòng)一點(diǎn)可以看到:

	*: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,$)

把這個(gè)使用方法對(duì)應(yīng)前面的命令,如下所示:

:       w               !sudo tee %
|       |               |  |
:[range]w[rite] [++opt] !{cmd}

我們并未指定range,參見幫助文檔最下面一行,當(dāng)range未指定時(shí),默認(rèn)情況下是整個(gè)文件。愛掏網(wǎng) - it200.com此外,這里也沒有指定opt。愛掏網(wǎng) - it200.com

Vim中執(zhí)行外部命令

接下來(lái)是一個(gè)嘆號(hào)!,它表示其后面部分是外部命令,即sudo tee %愛掏網(wǎng) - it200.com文檔中說(shuō)的很清楚,這和直接執(zhí)行:!{cmd}是一樣的效果。愛掏網(wǎng) - it200.com后者的作用是打開shell執(zhí)行一個(gè)命令,比如,運(yùn)行:!ls,會(huì)顯示當(dāng)前工作目錄下的所有文件,這非常有用,任何可以在shell中執(zhí)行的命令都可以在不退出Vim的情況下運(yùn)行,并且可以將結(jié)果讀入到Vim中來(lái)。愛掏網(wǎng) - it200.com試想,如果你要在Vim中插入當(dāng)前工作路徑或者當(dāng)前工作路徑下的所有文件名,你可以運(yùn)行:

:r !pwd或:r !ls

此時(shí)所有的內(nèi)容便被讀入至Vim,而不需要退出Vim,執(zhí)行命令,然后拷貝粘貼至Vim中。愛掏網(wǎng) - it200.com有了它,Vim可以自由的操作shell而無(wú)需退出。愛掏網(wǎng) - it200.com

命令的另一種表示形式

再看前面的文檔:

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

所以實(shí)際上這個(gè):w并未真的保存當(dāng)前文件,就像執(zhí)行:w new-file-name時(shí),它將當(dāng)前文件的內(nèi)容保存到另外一個(gè)new-file-name的文件中,在這里它相當(dāng)于一個(gè)另存為,而不是保存。愛掏網(wǎng) - it200.com它將當(dāng)前文檔的內(nèi)容寫到后面cmd的標(biāo)準(zhǔn)輸入中,再來(lái)執(zhí)行cmd,所以整個(gè)命令可以轉(zhuǎn)換為一個(gè)具有相同功能的普通shell命令:

$ cat readonly-file-name | sudo tee %

這樣看起來(lái)”正常”些了。愛掏網(wǎng) - it200.com其中sudo很好理解,意為切換至root執(zhí)行后面的命令,tee和%是什么呢?

%的意義

我們先來(lái)看%,執(zhí)行: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_%*

在執(zhí)行外部命令時(shí),%會(huì)擴(kuò)展成當(dāng)前文件名,所以上述的cmd也就成了sudo tee readonly-file-name愛掏網(wǎng) - it200.com此時(shí)整個(gè)命令即:

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

注意:在另外一個(gè)地方我們也經(jīng)常用到%,沒錯(cuò),替換。愛掏網(wǎng) - it200.com但是那里%的作用不一樣,執(zhí)行:help :%查看文檔:

Line numbers may be specified with: *:range* *E14* *{address}*
{number} an absolute line number
...
% equal to 1,$ (the entire file) *:%*

在替換中,%的意義是代表整個(gè)文件,而不是文件名。愛掏網(wǎng) - it200.com所以對(duì)于命令:%s/old/new/g,它表示的是替換整篇文檔中的old為new,而不是把文件名中的old換成new。愛掏網(wǎng) - it200.com

tee的作用

現(xiàn)在只剩一個(gè)難點(diǎn): tee。愛掏網(wǎng) - it200.com它究竟有何用?維基百科上對(duì)其有一個(gè)詳細(xì)的解釋,你也可以查看man page愛掏網(wǎng) - it200.com下面這幅圖很形象的展示了tee是如何工作的:

ls -l的輸出經(jīng)過(guò)管道傳給了tee,后者做了兩件事,首先拷貝一份數(shù)據(jù)到文件file.txt,同時(shí)再拷貝一份到其標(biāo)準(zhǔn)輸出。愛掏網(wǎng) - it200.com數(shù)據(jù)再次經(jīng)過(guò)管道傳給less的標(biāo)準(zhǔn)輸入,所以它在不影響原有管道的基礎(chǔ)上對(duì)數(shù)據(jù)作了一份拷貝并保存到文件中。愛掏網(wǎng) - it200.com看上圖中間部分,它很像大寫的字母T,給數(shù)據(jù)流動(dòng)增加了一個(gè)分支,tee的名字也由此而來(lái)。愛掏網(wǎng) - it200.com

現(xiàn)在上面的命令就容易理解了,tee將其標(biāo)準(zhǔn)輸入中的內(nèi)容寫到了readonly-file-name中,從而達(dá)到了更新只讀文件的目的。愛掏網(wǎng) - it200.com當(dāng)然這里其實(shí)還有另外一半數(shù)據(jù):tee的標(biāo)準(zhǔn)輸出,但因?yàn)楹竺鏇]有跟其它的命令,所以這份輸出相當(dāng)于被拋棄。愛掏網(wǎng) - it200.com當(dāng)然也可以在后面補(bǔ)上> /dev/null,以顯式的丟棄標(biāo)準(zhǔn)輸出,但是這對(duì)整個(gè)操作沒有影響,而且會(huì)增加輸入的字符數(shù),因此只需上述命令即可。愛掏網(wǎng) - it200.com

命令執(zhí)行之后

運(yùn)行完上述命令后,會(huì)出現(xiàn)下面的提示:

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提示文件更新,詢問(wèn)是確認(rèn)還是重新加載文件。愛掏網(wǎng) - it200.com建議直接輸入O,因?yàn)檫@樣可以保留Vim的工作狀態(tài),比如編輯歷史,buffer等,撤消等操作仍然可以繼續(xù)。愛掏網(wǎng) - it200.com而如果選擇L,文件會(huì)以全新的文件打開,所有的工作狀態(tài)便丟失了,此時(shí)無(wú)法執(zhí)行撤消,buffer中的內(nèi)容也被清空。愛掏網(wǎng) - it200.com

更簡(jiǎn)單的方案:映射

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

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

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

這樣,簡(jiǎn)單的運(yùn)行:w!!即可。愛掏網(wǎng) - it200.com命令后半部分> /dev/null在前面已經(jīng)解釋過(guò),作用為顯式的丟掉標(biāo)準(zhǔn)輸出的內(nèi)容。愛掏網(wǎng) - it200.com

另一種思路

至此,一個(gè)比較完美但很tricky的方案已經(jīng)完成。愛掏網(wǎng) - it200.com你可能會(huì)問(wèn),為什么不用下面這樣更常見的命令呢?這不是更容易理解,更簡(jiǎn)單一些么?

:w !sudo cat > %

重定向的問(wèn)題

我們來(lái)分析一遍,像前面一樣,它可以被轉(zhuǎn)換為相同功能的shell命令:

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

這條命令看起來(lái)一點(diǎn)問(wèn)題沒有,可一旦運(yùn)行,又會(huì)出現(xiàn)另外一個(gè)錯(cuò)誤:

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

shell returned 1

這是怎么回事?不是明明加了sudo么,為什么還提示說(shuō)沒有權(quán)限?稍安勿躁,原因在于重定向,它是由shell執(zhí)行的,在一切命令開始之前,shell便會(huì)執(zhí)行重定向操作,所以重定向并未受sudo影響,而當(dāng)前的shell本身也是以普通用戶身份啟動(dòng),也沒有權(quán)限寫此文件,因此便有了上面的錯(cuò)誤。愛掏網(wǎng) - it200.com

重定向方案

這里介紹了幾種解決重定向無(wú)權(quán)限錯(cuò)誤的方法,當(dāng)然除了tee方案以外,還有一種比較方便的方案:以sudo打開一個(gè)shell,然后在該具有root權(quán)限的shell中執(zhí)行含重定向的命令,如:

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

可是這樣執(zhí)行時(shí),由于單引號(hào)的存在,所以在Vim中%并不會(huì)展開,它被原封不動(dòng)的傳給了shell,而在shell中,一個(gè)單獨(dú)的%相當(dāng)于nil,所以文件被重定向到了nil,所有內(nèi)容丟失,保存文件失敗。愛掏網(wǎng) - it200.com

既然是由于%沒有展開導(dǎo)致的錯(cuò)誤,那么試著將單引號(hào)'換成雙引號(hào)"再試一次:

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

成功!這是因?yàn)樵趯⒚顐鞯絪hell去之前,%已經(jīng)被擴(kuò)展為當(dāng)前的文件名。愛掏網(wǎng) - it200.com有關(guān)單引號(hào)和雙引號(hào)的區(qū)別可以參考這里,簡(jiǎn)單的說(shuō)就是單引號(hào)會(huì)將其內(nèi)部的內(nèi)容原封不動(dòng)的傳給命令,但是雙引號(hào)會(huì)展開一些內(nèi)容,比如變量,轉(zhuǎn)義字符等。愛掏網(wǎng) - it200.com

當(dāng)然,也可以像前面一樣將它映射為一個(gè)簡(jiǎn)單的命令并添加到.vimrc中:

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

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

注意:這里不再需要把輸出重定向到/dev/null中。愛掏網(wǎng) - it200.com

寫在結(jié)尾

至此,借助Vim強(qiáng)大的靈活性,實(shí)現(xiàn)了兩種方案,可以在以普通用戶啟動(dòng)的Vim中保存需root權(quán)限的文件。愛掏網(wǎng) - it200.com兩者的原理類似,都是利用了Vim可以執(zhí)行外部命令這一特性,區(qū)別在于使用不同的shell命令。愛掏網(wǎng) - it200.com如果你還有其它的方案,歡迎給我留言。愛掏網(wǎng) - it200.com

(全文完)

feihu

2024.07.30 于 Shenzhen

聲明:所有內(nèi)容來(lái)自互聯(lián)網(wǎng)搜索結(jié)果,不保證100%準(zhǔn)確性,僅供參考。如若本站內(nèi)容侵犯了原著者的合法權(quán)益,可聯(lián)系我們進(jìn)行處理。
發(fā)表評(píng)論
更多 網(wǎng)友評(píng)論0 條評(píng)論)
暫無(wú)評(píng)論

返回頂部

亚洲国产爱久久全部精品_日韩有码在线播放_国产欧美在线观看_中文字幕不卡在线观看

    
    

    欧美激情在线| 夜夜嗨av一区二区三区网站四季av | 国产精品jizz在线观看美国| 欧美亚洲一区二区在线| 精品不卡一区| 国产欧美在线观看一区| 欧美精品福利视频| 久久综合色婷婷| 欧美一级在线亚洲天堂| 一本色道久久综合亚洲精品不| 国产在线视频不卡二| 国产精品日韩欧美一区二区| 欧美国产日韩精品| 免费中文日韩| 狂野欧美激情性xxxx| 久久福利资源站| 亚洲欧美日韩精品久久久| 亚洲作爱视频| 一区二区久久久久久| 99国产精品久久久久久久| 在线欧美日韩| 在线欧美日韩国产| 在线观看一区| 今天的高清视频免费播放成人| 国产伦精品一区二区三区在线观看| 欧美日韩一区自拍| 欧美日韩免费观看一区三区| 欧美精品一区二区三区蜜桃| 欧美91福利在线观看| 毛片一区二区三区| 欧美aa国产视频| 欧美va天堂在线| 欧美国产精品中文字幕| 欧美高清不卡| 欧美日韩国产在线| 国产精品高清在线观看| 国产精品久久久免费| 国产精品久久久久久久久久久久久久| 欧美三级电影精品| 国产精品久久中文| 韩国av一区二区| 91久久久在线| 亚洲小说春色综合另类电影| 午夜精品99久久免费| 久久精品视频免费播放| 蘑菇福利视频一区播放| 欧美日韩国产亚洲一区| 欧美丝袜一区二区| 国产美女精品| 亚洲欧洲一区二区三区久久| 国产精品99久久久久久www| 午夜精品免费| 免费短视频成人日韩| 欧美午夜片欧美片在线观看| 国产视频一区三区| 日韩视频在线观看| 亚洲欧美在线另类| 欧美大片在线看| 国产精品男人爽免费视频1| 黄色精品免费| 亚洲一区二区三区在线看| 久久久综合免费视频| 欧美日韩国产一区二区三区地区| 国产精品免费视频xxxx| 亚洲国产美女| 欧美专区第一页| 欧美极品一区| 激情欧美一区二区三区| 宅男噜噜噜66一区二区66| 久久久久一区二区| 国产精品卡一卡二| 亚洲乱码国产乱码精品精| 久久久久久久久久久成人| 欧美日韩裸体免费视频| 精品999网站| 欧美一区国产在线| 国产精品sm| 亚洲精品视频在线观看网站| 久久久国产视频91| 国产欧美精品在线播放| 一本色道久久综合| 欧美激情综合在线| 在线观看一区二区精品视频| 欧美一区二区三区成人| 欧美视频免费在线| 亚洲精品美女在线| 蜜臀av性久久久久蜜臀aⅴ四虎| 国产欧美一级| 香蕉视频成人在线观看| 国产精品美女诱惑| 亚洲一区二区三区在线| 欧美日韩国产电影| 日韩视频久久| 欧美精品七区| 亚洲精品一区二区三区樱花| 欧美成ee人免费视频| 亚洲电影观看| 欧美 日韩 国产一区二区在线视频 | 欧美jjzz| 亚洲人成人一区二区三区| 另类天堂av| 亚洲国内欧美| 欧美日韩不卡一区| 一区二区高清视频在线观看| 欧美日韩亚洲免费| 亚洲直播在线一区| 国产精品久久一级| 久久不射电影网| 影视先锋久久| 欧美区在线播放| 宅男噜噜噜66一区二区| 国产精品欧美激情| 欧美一区久久| 亚洲国产欧美一区二区三区同亚洲 | 亚洲视频在线视频| 国产精品亚洲片夜色在线| 欧美一区视频| 亚洲人成艺术| 国产精品久久久久久超碰| 久久国产福利国产秒拍| 亚洲成人资源网| 欧美日韩精品在线观看| 午夜精品久久久久久久| 亚洲大胆美女视频| 国产精品成人午夜| 久久精品女人| 一区二区日韩精品| 国内精品免费在线观看| 欧美精品午夜| 久久精品国产一区二区三| 亚洲欧洲在线播放| 国产色视频一区| 欧美韩日一区| 久久精品国产亚洲一区二区三区| 亚洲激情六月丁香| 国产婷婷一区二区| 欧美系列电影免费观看| 久久综合亚洲社区| 亚洲欧美制服另类日韩| 亚洲欧洲日本在线| 国产亚洲欧洲997久久综合| 欧美肉体xxxx裸体137大胆| 久久精品国产一区二区三区免费看| 亚洲精品视频一区二区三区| 国产农村妇女精品一区二区| 欧美日本在线播放| 久久久久久九九九九| 亚洲欧美激情视频| 在线视频精品一区| 91久久精品国产91久久| 韩日成人在线| 国产日韩精品一区观看| 国产精品第2页| 欧美日韩国产精品| 欧美激情麻豆| 欧美激情视频免费观看| 毛片一区二区| 久久夜色精品国产欧美乱| 欧美一区二区网站| 校园激情久久| 欧美一区二区啪啪| 亚洲一区激情| 亚洲天堂男人| 亚洲在线成人| 亚洲欧美另类在线观看| 亚洲欧美一级二级三级| 亚洲综合二区| 欧美一二三区在线观看| 欧美一区永久视频免费观看| 亚洲在线一区| 久久黄色小说| 久久日韩粉嫩一区二区三区| 久久精品天堂| 麻豆91精品91久久久的内涵| 另类尿喷潮videofree| 欧美va亚洲va香蕉在线| 欧美国产亚洲精品久久久8v| 欧美成年人视频网站欧美| 免费成人在线视频网站| 欧美激情第二页| 欧美日韩一区二区高清| 国产精品毛片一区二区三区| 国产精品久久久久久久浪潮网站| 国产精品一区二区三区四区| 国产模特精品视频久久久久| 韩国av一区二区三区| 91久久国产精品91久久性色| 99re6热在线精品视频播放速度| 一区二区三区精密机械公司| 亚洲欧美日本视频在线观看| 久久久久九九视频| 欧美精品国产一区| 欧美小视频在线| 国产综合色产| 日韩亚洲欧美中文三级| 欧美一区二区三区播放老司机| 免费不卡视频| 欧美午夜剧场| 亚洲高清网站| 亚洲欧美日韩精品久久亚洲区|