“සුඩෝ සමඟ ලිවීම” උපක්‍රමය ක්‍රියා කරන්නේ කෙසේද?


1429

සුඩෝ සමඟ vim විවෘත කිරීමට ඔබට අමතක වූ විට පවා, මූල අවසරය අවශ්‍ය ගොනුවක ලිවීමට ඔබට ඉඩ දෙන විධානය ඔබ බොහෝ දෙනෙක් දැක ඇති:

:w !sudo tee %

කාරණය නම් මෙහි හරියටම සිදුවෙමින් පවතින දේ මට නොලැබීමයි.

මම දැනටමත් මෙය හදුනාගෙන ඇත: 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 |:!|.

එබැවින් එය සියලු රේඛා සම්මත ආදානය ලෙස පසු කරයි.

මෙම !sudo teeකොටස සිටී teeපරිපාලක වරප්රසාද හිමි.

සියල්ලන්ටම අර්ථවත් කිරීම සඳහා, %ගොනු නාමය ප්‍රතිදානය කළ යුතුය (සඳහා පරාමිතියක් ලෙස tee), නමුත් මෙම හැසිරීම සඳහා උපකාරය පිළිබඳ සඳහනක් මට සොයාගත නොහැක.

tl; dr මෙම විධානය විසුරුවා හැරීමට යමෙකුට මට උදව් කළ හැකිද?


5
Athan නාතන්: එසේම :w !sudo cat > %ක්‍රියා නොකරනු ඇති අතර සම්මත ප්‍රතිදානය දූෂණය නොකරන්නේද?
Bjarke Freund-Hansen

51
jbjarkef - නැත, එය ක්‍රියා නොකරයි. එවැනි අවස්ථාවකදී, sudoඅදාළ වේ cat, නමුත් එසේ නොවේ >, එබැවින් එයට අවසර නැත. ඔබට සම්පූර්ණ විධානයම සුඩෝ උප කුලකයකින් ධාවනය කිරීමට උත්සාහ කළ හැකිය :w !sudo sh -c "cat % > yams.txt", නමුත් එය ක්‍රියා නොකරනු ඇත, මන්ද උපසිරැසියෙහි %එය නිල් ය; ඔබ ඔබේ ගොනුවේ අන්තර්ගතය හිස් කරයි.
නේතන් ලෝන්ග්

3
එම විධානය ටයිප් කිරීමෙන් පසු අනතුරු ඇඟවීමේ පණිවිඩයක් දිස්වනු ඇතැයි මම සිතමි. එසේ නම්, L ඔබන්න. එවිට, ඔබ එන්ටර් ඔබන්න. කරන්න, අවසානයේදී ඔබේ ගොනුව සුරැකෙනු ඇත.
pablofiumara

9
AtherNathanLong nknittl: :w !sudo sh -c "cat >%"ඇත්ත වශයෙන්ම ක්‍රියා sudo tee %කරන්නේ Vim විසින් ගොනු නාමය උපසෙල් වෙත %පැමිණීමට පෙර ආදේශ කරන බැවිනි . කෙසේ වෙතත්, ගොනු නාමයේ අවකාශයක් තිබේ නම් ඒ දෙකම ක්‍රියා නොකරයි; ඔබ කළ යුත්තේ :w !sudo sh -c "cat >'%'"හෝ :w !sudo tee "%"එය නිවැරදි කිරීමයි.
හැන් සෝල්-ඕ

1
භාවිතයෙන් සුරකින්න: W සහ ගොනුව නැවත පූරණය කරන්න: විධානය W: execute ': නිශ්ශබ්ද w! Sudo tee%> / dev / null' | :සංස්කරණය කරන්න!
ඩියාගෝ රොබර්ටෝ ඩොස් සැන්ටොස්

Answers:


1626

තුළ :w !sudo tee %...

% එහි තේරුම "වත්මන් ගොනුව"

ලෙස ඉයුජින් y පෙන්වා , %ඇත්ත වශයෙන්ම කිරීමට සමත් වන "වත්මන් ගොනු නාමය", ඉන් අදහස් කරන්නේ කුමක්ද teeඑය මතලිවීමට වන ගොනු දන්නා නිසා බවයි.

(ආදේශන විධාන දී, එය තරමක් වෙනස් වේ; ලෙස :help :%දර්ශන, ඒක equal to 1,$ (the entire file). (මෙම ගොනු නාමය කිරීමට ඇගයීමට නොවන බව පෙන්වා දෙමින් සඳහා @Orafu ස්තුතිවන්ත වන්නට) උදාහරණයක් ලෙස, :%s/foo/bar"යනු වර්තමාන ගොනුව තුළ , සිදුවීම් වෙනුවට fooසමග bar." නම් ඔබ කැපී පෙනෙන ටයිප් කිරීමට පෙර යම් පෙළක් :s, උද්දීපනය කළ රේඛා %ඔබේ ආදේශන පරාසය ලෙස සලකන බව ඔබට පෙනෙනු ඇත.)

:w ඔබගේ ගොනුව යාවත්කාලීන නොකරයි

මෙම උපක්‍රමයේ එක් ව්‍යාකූල කොටසක් :wනම් ඔබේ ගොනුව වෙනස් කිරීම යැයි ඔබ සිතනු ඇත, නමුත් එය එසේ නොවේ. ඔබ විවෘත කර වෙනස් කර ඇත්නම් file1.txt, පසුව දිව්වා නම් :w file2.txt, එය "ලෙස සුරකින්න" වනු ඇත; file1.txtවෙනස් නොකරනු ඇත, නමුත් වත්මන් බෆරයේ අන්තර්ගතය වෙත යවනු ලැබේ file2.txt.

ඒ වෙනුවට file2.txt, ඔබට බෆරයේ අන්තර්ගතය ලබා ගැනීම සඳහා ෂෙල් විධානයක් ආදේශ කළ හැකිය . උදාහරණයක් ලෙස, :w !catඅන්තර්ගතය පෙන්වනු ඇත.

Vim සුඩෝ ප්‍රවේශය සමඟ ධාවනය :wනොවූයේ නම්, එයට ආරක්ෂිත ගොනුවක් වෙනස් කළ නොහැක, නමුත් එය බෆරයේ අන්තර්ගතය කවචයට යවන්නේ නම්, කවචයේ විධානයක් sudo සමඟ ධාවනය කළ හැකිය . මෙම අවස්ථාවේ දී, අපි භාවිතා කරමු tee.

තේ තේරුම් ගැනීම

සඳහා පරිදි tee, මේ පින්තූරේ teeසාමාන්ය bash පයිප්ප සවි තත්වය තුල ටී-හැඩයේ නල ලෙස විධානය: එය නිශ්චිත ගොනු (ව) සඳහා ප්රතිදාන මඟපෙන්වීම හා ද සම්මත ප්රතිදානය වෙත යවයි ඉදිරි නල විධානය විසින් අල්ලා ගත හැකි.

උදාහරණයක් ලෙස, ps -ax | tee processes.txt | grep 'foo', ක්රියාවලීන් ලැයිස්තුව පෙළ ගොනුව වෙත ලියනු ලැබේ සහ කිරීමට නැත්තෝ grep.

     +-----------+    tee     +------------+
     |           |  --------  |            |
     | ps -ax    |  --------  | grep 'foo' |
     |           |     ||     |            |
     +-----------+     ||     +------------+
                       ||   
               +---------------+
               |               |
               | processes.txt |
               |               |
               +---------------+

(රූප සටහන Asciiflow සමඟ නිර්මාණය කර ඇත .)

වැඩි විස්තර සඳහා teeman පිටුව බලන්න .

ටී හැක් එකක් ලෙස

ඔබගේ ප්‍රශ්නය විස්තර කරන තත්වය තුළ, භාවිතා teeකිරීම අනවසරයෙන් සිදු වන බැවින් එය කරන දෙයින් අඩක් අපි නොසලකා හරිමු . sudo teeඅපගේ ගොනුවට ලියන අතර බෆරයේ අන්තර්ගතය සම්මත ප්‍රතිදානය වෙත යවයි, නමුත් අපි සම්මත ප්‍රතිදානය නොසලකා හරිමු . මෙම නඩුවේදී අපට වෙනත් නල විධානයකට කිසිවක් යැවීමට අවශ්‍ය නැත; අපි teeගොනුවක් ලිවීමේ විකල්ප ක්‍රමයක් ලෙස භාවිතා කරන අතර එමඟින් අපට එය ඇමතිය හැකිය sudo.

මෙම උපක්‍රමය පහසු කිරීම

.vimrcමෙම උපක්‍රමය භාවිතයට පහසු කිරීම සඳහා ඔබට මෙය එකතු කළ හැකිය : ටයිප් කරන්න :w!!.

" Allow saving of files as sudo when I forgot to start vim using sudo.
cmap w!! w !sudo tee > /dev/null %

මෙම > /dev/nullකොටස සම්මත ප්‍රතිදානය පැහැදිලිවම ඉවත දමයි, මන්ද මා කී පරිදි, අපට වෙනත් නල විධානයකට කිසිවක් යැවීමට අවශ්‍ය නැත.


150
විශේෂයෙන් ඔබේ අංකනය "w !!" එය "සුඩෝ !!" භාවිතා කිරීමෙන් පසු මතක තබා ගැනීම පහසුය. විධාන රේඛාවේ.
අයිඩාන් කේන්

11
එබැවින් මෙය teeගොනුවකට stdin ලිවීමේ හැකියාව සඳහා භාවිතා කරයි . මට පුදුමයි, එය කිරීම කාගේ කාර්යයක්ද යන්න (මම කවදාවත් අසා නැති වැඩසටහනක් හමු වූ spongeඅතර මෙය සිදු කරයි). මම හිතන්නේ සාමාන්‍යයෙන් "ගොනුවකට ධාරාවක් ලියන්න" සිදු කරනු ලබන්නේ කවචයක් තුළිනි. විම්ගේ !{cmd}කටුව දෙබලකින් cmdනොවේද ( ඒ වෙනුවට දෙබලක )? සමහර විට වඩා පැහැදිලිව පෙනෙන දෙයක් වනුයේ වැඩකරන ප්‍රභේදයක් sh -c ">"වෙනුවට භාවිතා කිරීමයි tee.
ස්ටීවන් ලූ

2
Te ස්ටීවන් ලූ: ඩේබියන් පදනම් කරගත් ඩිස්ට්‍රෝස් හැර සෑම බෙදාහැරීමකම පැකේජයේ spongeකොටසකි moreutils. moreutilsවැනි වඩා පොදු මෙවලම් හා සම බව සමහර ලස්සන ලස්සන මෙවලම් xargsහා tee.
ස්විස්

10
වෙනස් කළ ගොනු අන්තර්ගතයන් වත්මන් බෆරයට ස්වයංක්‍රීයව පැටවීමට vim ට පැවසීමට මෙම අන්වර්ථය පුළුල් කරන්නේ කෙසේද? එය මගෙන් එය ඉල්ලයි, එය ස්වයංක්‍රීය කරන්නේ කෙසේද?
ස්ලැට්කෝ

10
24 user247077: එවැනි අවස්ථාවකදී, catroot ලෙස ධාවනය වන අතර ප්‍රතිදානය shell ලෙස හරවා යවනු ලැබේ, එය root ලෙස ක්‍රියාත්මක නොවේ. එය සමාන ය echo hi > /read/only/file.
WhyNotHugo

99

ක්රියාත්මක කළ විධාන රේඛාව තුළ, %සඳහා නැගී වර්තමාන ගොනුව නම . මෙය ලේඛනගත කර ඇත්තේ :help cmdline-special:

In Ex commands, at places where a file name can be used, the following
characters have a special meaning.
        %       Is replaced with the current file name.

ඔබ දැනටමත් සොයාගෙන ඇති පරිදි, :w !cmdවත්මන් බෆරයේ අන්තර්ගතය වෙනත් විධානයකට නල කරන්න. කුමක්ද teeකරන්නේ ගොනු එකක් හෝ වැඩි කිරීමට, සහ ද සම්මත ප්රතිදානය වෙත සම්මත ආදාන පිටපත් වේ. එම නිසා, :w !sudo tee % > /dev/nullවත්මන් බෆරයේ අන්තර්ගතය root වන අතරතුර වත්මන් ගොනුවට effectively ලදායී ලෙස ලියයි . මේ සඳහා භාවිතා කළ හැකි තවත් විධානයක් නම් dd:

:w !sudo dd of=% > /dev/null

කෙටිමඟක් ලෙස, ඔබට මෙම සිතියම්කරණය ඔබගේ .vimrc:

" Force saving files that require root permission 
cnoremap w!! w !sudo tee > /dev/null %

ඉහත සඳහන් දෑ සමඟ :w!!<Enter>ගොනුව root ලෙස සුරැකීමට ටයිප් කළ හැකිය .


1
සිත්ගන්නාසුලු, :help _%ඔබ ඇතුළු කළ :help %දේ ගෙන එයි , නමුත් වරහන් ගැලපෙන යතුර ගෙන එයි. අවධාරනය කළ උපසර්ගය උත්සාහ කිරීමට මා සිතුවේ නැත, එය කිසියම් ආකාරයක රටාවක් ද? උදව් සොයන විට උත්සාහ කළ යුතු වෙනත් 'විශේෂ' දේවල් තිබේද?
ඩේවිඩ් පාප්

2
Av ඩේවිඩ්: helpවිධානය ටැගයකට පනිනවා . ඔබට ලබා ගත හැකි ටැග්ස් දැකිය හැකිය :h help-tags. ගැලපෙන ටැග් බැලීමට ඔබට විධාන රේඛා සම්පුර්ණ කිරීම ද භාවිතා කළ හැකිය: :h cmdline<Ctrl-D>(හෝ :h cmdline<Tab>ඔබ ඒ wildmodeඅනුව සකසා ඇත්නම් )
ඉයුජින් යර්මාෂ්

1
මම භාවිතා කිරීමට සිදු cmap w!! w !sudo tee % > /dev/nullමෙම කාර්යය කර ගැනීම මගේ .vimrc ගොනුවේ. යනු %ඉහත පිළිතුර අහලකටවත්? (මෙහි කිසිදු විශේෂ expert
යෙක්

@DMfll ඔව්. පිළිතුරෙහි ඇති විධානයෙහි ප්‍රති result ලය වනු ඇත්තේ sudo tee > /dev/null /path/to/current/fileසැබවින්ම තේරුමක් නැති බවය. (එය සංස්කරණය කිරීමට යයි)
jazzpi

1
@ ජස්පී: ඔබ වැරදියි. විධාන රේඛාවේ ඔබ ගොනු හරවා යැවීම සිදු කරන්නේ කොතැනදැයි ෂෙල්ස් සැබවින්ම ගණන් ගන්නේ නැත.
ඉයුජින් යර්මාෂ්

19

:w - ගොනුවක් ලියන්න.

!sudo - shell sudo විධානය අමතන්න.

tee- ලිවීම (vim: w) විධානයෙහි ප්‍රතිදානය ටී භාවිතයෙන් හරවා යවනු ලැබේ. % යනු වර්තමාන ගොනුවේ නම එනම් /etc/apache2/conf.d/mediawiki.conf මිස අන් කිසිවක් නොවේ. වෙනත් වචන වලින් කිවහොත්, තේ විධානය root ලෙස ක්‍රියාත්මක වන අතර එය සම්මත ආදානය ගෙන එය% මගින් නිරූපණය කරන ගොනුවකට ලියන්න. කෙසේ වෙතත්, මෙය නැවත ගොනුව නැවත පූරණය කිරීමට විමසනු ඇත (vim හි වෙනස්කම් පැටවීමට L ඔබන්න):

නිබන්ධන සබැඳිය


19

මෙයද හොඳින් ක්‍රියාත්මක වේ:

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

@ නාතන් ලෝන්ග්ගේ අදහස් දැක්වීමෙන් මෙය ආශ්වාදයක් ලැබීය.

දැන්වීම :

"ෂෙල් වෙත යාමට පෙර පුළුල් කිරීමට 'අවශ්‍ය නිසා ඒ වෙනුවට භාවිතා කළ යුතුය %.


11
මෙය ක්‍රියාත්මක විය හැකි අතර, එය බහු වැඩසටහන් සඳහා (ෂෝ සහ කැට්) සුඩෝ ප්‍රවේශය ලබා දෙයි. අනෙක් උදාහරණ වෙනුවට වඩා ආරක්ෂිත විය හැකි teeසමග /usr/bin/teePATH-වෙනස් ප්රහාර වැළැක්වීම සඳහා.
idbrii

10

පිළිගත් පිළිතුර ඒ සියල්ල ආවරණය කරයි, එබැවින් මම භාවිතා කරන කෙටිමඟකට තවත් උදාහරණයක් වාර්තාව සඳහා දෙන්නෙමි.

එය ඔබගේ etc/vim/vimrc(හෝ ~/.vimrc) වෙත එක් කරන්න :

  • cnoremap w!! execute 'silent! write !sudo tee % >/dev/null' <bar> edit!

කොහෙද:

  • cnoremap: පහත දැක්වෙන කෙටිමඟ විධාන රේඛාවට සම්බන්ධ කළ යුතු බව vim ට පවසයි .
  • w!!: කෙටිමඟම.
  • execute '...': පහත දැක්වෙන දාමය ක්‍රියාත්මක කරන විධානයකි.
  • silent!: එය නිහ .ව ධාවනය කරන්න
  • write !sudo tee % >/dev/null: OP ප්‍රශ්නය, NULLපිරිසිදු විධානයක් සඳහා පණිවිඩ නැවත හරවා යැවීමක් එක් කළේය
  • <bar> edit!: මෙම උපක්‍රමය කේක් එකේ චෙරි ය: එය editබෆරය නැවත පූරණය කිරීමේ විධානය ද පසුව බෆරය වෙනස් වී ඇති පණිවිඩ වළක්වා ගන්න . මෙහි විධාන දෙකක් වෙන් කිරීම <bar>සඳහා පයිප්ප සංකේතය ලියන්නේ කෙසේද යන්නයි .

එය උපකාරී වේ යැයි සිතමි. වෙනත් ගැටළු සඳහාද බලන්න:


නිහ silent යි! මුරපද විමසුම අක්‍රීය කර ඇති බැවින් ඔබට එය නොපෙනේ
ඇන්ඩි රේ

7

"මගේ ගොනුව විවෘත කිරීමේදී මට ලිවීමට අමතකsudo වූ " කලාපයට තවත් ප්‍රවේශයක් යෝජනා කිරීමට මම කැමතියි :

A ලැබීම permission deniedසහ ටයිප් කිරීම වෙනුවට :w!!, ගොනු හිමිකරු නම් කොන්දේසි සහිත vimවිධානයක් තිබීම වඩාත් අලංකාර බව මට පෙනේ .sudo vimroot

මෙය ක්‍රියාත්මක කිරීම පහසුය (ඊටත් වඩා අලංකාර ක්‍රියාත්මක කිරීම් තිබිය හැකිය, මම පැහැදිලිවම බැෂ්-ගුරු නොවේ):

function vim(){
  OWNER=$(stat -c '%U' $1)
  if [[ "$OWNER" == "root" ]]; then
    sudo /usr/bin/vim $*;
  else
    /usr/bin/vim $*;
  fi
}

එය හොඳින් ක්‍රියාත්මක වේ.

මෙය එක් bashඅයෙකුට වඩා කේන්ද්‍රීය ප්‍රවේශයකි, vimඑබැවින් සෑම කෙනෙකුම එයට කැමති නොවනු ඇත.

ඇත්ත වශයෙන්:

  • එය අසමත් වන අවස්ථා තිබේ (ගොනු හිමිකරු අවශ්‍ය නොවන rootනමුත් අවශ්‍ය වූ විට sudo, නමුත් ශ්‍රිතය කෙසේ හෝ සංස්කරණය කළ හැකිය)
  • vimගොනුවක් කියවීමට පමණක් භාවිතා කිරීමේදී එය තේරුමක් නැත (මා සිතන පරිදි, මම භාවිතා කරන්නේ tailහෝ catකුඩා ලිපිගොනු සඳහා)

නමුත් මෙය වඩා හොඳ dev පරිශීලක අත්දැකීමක් ගෙන එන බව මට පෙනී ගියේය, එය භාවිතා කරන විට IMHO අමතක කිරීමට නැඹුරු වේ bash. :-)


5
මෙය සමාව දීම අඩු බව මතක තබා ගන්න. පෞද්ගලිකව, මගේ බොහෝ වැරදි මෝඩ වැරදි ය. ඒ නිසා මම මෝඩ හා ප්‍රතිවිපාක විය හැකි යමක් කරන විට හිස ඔසවන්නට කැමැත්තෙමි. මෙය ඇත්ත වශයෙන්ම මනාපයක් වන නමුත් වරප්‍රසාද ඉහළ නැංවීම හෘද සාක්ෂියට එකඟව කළ යුතු ක්‍රියාවකි. එසේම: ඔබ මෙය බොහෝ විට අත්විඳින්නේ නම් ": w !!" නිශ්ශබ්දව ස්වයංක්‍රීයව සූඩෝ කිරීමට කරදරයක් ඇති නමුත් (හිමිකරු = මූල නම් පමණි); ඔබගේ වර්තමාන කාර්ය ප්‍රවාහය පරීක්ෂා කිරීමට ඔබට අවශ්‍ය විය හැකිය.
Payne

rootමුරපදය විමසන විට ගොනුව විවෘත කරන විට සිත්ගන්නාසුලු අදහස් දැක්වීමක් කළ යුතුය .
ඔගස්ටින් රයිඩින්ගර්

ආ! වෙනසක් තියෙනවා. එය රඳා පවතින්නේ sudo පරිශීලකයාට "NOPASSWD" කට්ටලයක් තිබේද නැද්ද යන්නයි.
Payne

එවිට NOPASSWD තිබීම අඩු සමාව දෙන දෙයකි ... :)
ඔගස්ටින් රයිඩින්ගර්

4

නියොවිම් සඳහා

අන්තර්ක්‍රියාකාරී ඇමතුම් ( https://github.com/neovim/neovim/issues/1716 ) සමඟ ඇති ගැටළු හේතුවෙන් , මම මෙය නියෝවිම් සඳහා භාවිතා කරමි, ආචාර්ය බෙකෝගේ පිළිතුර මත පදනම්ව:

cnoremap w!! execute 'silent! write !SUDO_ASKPASS=`which ssh-askpass` sudo tee % >/dev/null' <bar> edit!

මෙය ssh-askpassසුඩෝ මුරපදය ඉල්ලමින් සංවාදයක් විවෘත කරනු ඇත .

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.