ভিম "সুডো দিয়ে লিখুন" কৌশলটি কীভাবে কাজ করে?


1410

আপনারা অনেকেই সম্ভবত কমান্ডটি দেখেছেন যা আপনাকে এমন কোনও ফাইলে লিখতে দেয় যা রুট অনুমতি দরকার, এমনকি আপনি যখন sudo দিয়ে ভিএম খুলতে ভুলে গিয়েছিলেন:

: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
@ নাথান: :w !sudo cat > %স্ট্যান্ডার্ড আউটপুটকে দূষিত করবে না পাশাপাশি কাজ করবে না?
বার্জার ফ্রেইন্ড-হানসেন

51
@ বারজারেফ - না, এটি কাজ করে না। সেক্ষেত্রে, sudoপ্রয়োগ করা হয় cat, কিন্তু না করতে >, তাই এটি অনুমোদিত নয়। আপনি পুরো কমান্ডটি একটি সুডো সাবশেলে চালানোর চেষ্টা করতে পারেন :w !sudo sh -c "cat % > yams.txt", যেমন , তবে এটি কোনওভাবেই কাজ করে না, কারণ সাব-শেল- %এ শূন্য; আপনি আপনার ফাইলের বিষয়বস্তু ফাঁকা রাখবেন।
নাথান লং

3
আমি কেবল যুক্ত করতে চাই যে এই আদেশটি টাইপ করার পরে, একটি সতর্কতা বার্তা উপস্থিত হতে পারে। যদি তা হয় তবে এল টিপুন, তারপরে আপনাকে এন্টার টিপতে বলা হবে। করবেন এবং শেষ পর্যন্ত আপনার ফাইলটি সংরক্ষণ হবে।
পাবলোফিউমারা

9
@ নাথানলং @ ক্যানিটল: :w !sudo sh -c "cat >%"বাস্তবে ঠিক ঠিক তেমনি কাজ করে sudo tee %কারণ ভিম ফাইলের নামটি সাবস্কেলে %যাওয়ার আগে ফাইলের পরিবর্তে প্রতিস্থাপন করে । যাইহোক, ফাইলনামের ফাঁকে ফাঁকে ফাঁকা জায়গা রাখলে উভয়ই কাজ করে না; আপনাকে করতে হবে :w !sudo sh -c "cat >'%'"বা :w !sudo tee "%"এটি ঠিক করতে হবে।
হান সিওল-ওহ

1
ব্যবহার করে সংরক্ষণ করুন: ডাব্লু এবং ফাইলটি পুনরায় লোড করুন: কমান্ড ডাব্লু: এক্সিকিউট ': নীরব ডাব্লু! Sudo tee%> / dev / null' | : সম্পাদনা!
দিয়েগো রবার্তো ডস সান্টোস

উত্তর:


1610

ইন :w !sudo tee %...

% অর্থ "বর্তমান ফাইল"

ইউজিন ওয়াই যেমন উল্লেখ করেছেন , %প্রকৃতপক্ষে "বর্তমান ফাইলের নাম" এর অর্থ কি এটি পাস হয়েছে 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কেবল সামগ্রীগুলি প্রদর্শিত হবে will

যদি ভিম সুডো অ্যাক্সেসের সাথে চালিত :wনা হয় তবে এটি কোনও সুরক্ষিত ফাইল পরিবর্তন করতে পারে না, তবে এটি শফারে বাফার সামগ্রীগুলি পাস করলে শেলটিতে একটি কমান্ড sudo দিয়ে চালানো যেতে পারে । এই ক্ষেত্রে, আমরা ব্যবহার tee

টি বোঝা

যেমন হিসাবে tee, teeকমান্ডটি একটি টিপ-আকারের পাইপ হিসাবে একটি সাধারণ ব্যাশ পাইপিং পরিস্থিতিতে চিত্র করুন: এটি আউটপুটকে নির্দিষ্ট ফাইলগুলিতে নির্দেশ দেয় এবং এটি স্ট্যান্ডার্ড আউটপুটেও প্রেরণ করে , যা পরবর্তী পাইপ কমান্ড দ্বারা ক্যাপচার করা যায়।

উদাহরণস্বরূপ, মধ্যে ps -ax | tee processes.txt | grep 'foo', প্রক্রিয়াগুলির তালিকা কোনও পাঠ্য ফাইলে লিখিত হবে এবং এর সাথে পাস করা হবে grep

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

( এসিইফ্লো দিয়ে চিত্রটি তৈরি করা হয়েছে ))

দেখুন 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অংশ স্পষ্টভাবে মান আউটপুট দূরে ছোঁড়ার, যেহেতু, আমি আগেই বলেছি, আমরা অন্য পাইপ কমান্ড কিছু পাস প্রয়োজন হবে না।


147
বিশেষত আপনার স্বরলিপি "ডাব্লু !!" যা "sudo !!" ব্যবহারের পরে মনে রাখা এত সহজ! কমান্ড লাইনে।
আইডন কেন

11
সুতরাং এটি teeস্ট্যান্ডিন কোনও ফাইলে লেখার ক্ষমতার জন্য ব্যবহার করে। আমি আশ্চর্য হয়েছি যে এমন কোনও প্রোগ্রাম নেই যার কাজটি করা (আমি এমন একটি প্রোগ্রাম পেয়েছি spongeযা আমি কখনও শুনিনি যা বলে এটি করা হয়)। আমার ধারণা, সাধারণত "কোনও ফাইলের কাছে একটি স্ট্রিম লিখুন" অন্তর্নির্মিত শেল দ্বারা সঞ্চালিত হয়। ভিম কি !{cmd}শেলটি কাঁটাচ্ছে cmdনা ( পরিবর্তে কাঁটাচামচ করছে )? সম্ভবত কিছু যা আরও সুস্পষ্ট তার sh -c ">"পরিবর্তে কিছু কার্যকরী রূপ ব্যবহার করা হবে tee
স্টিভেন লু

2
@ স্টিভেন লু: দেবিয়ান ভিত্তিক ডিস্ট্রোস ব্যতীত প্রতিটি বিতরণে প্যাকেজের spongeঅংশ moreutilsmoreutilsকিছু বেশ সুন্দর সরঞ্জাম রয়েছে যা আরও সাধারণ সরঞ্জাম xargsএবং এর মতো সমান tee
সুইস

10
বর্তমান বাফারে পরিবর্তিত ফাইলের সামগ্রীগুলি স্বয়ংক্রিয়ভাবে লোড করতে ভিএমকে বলতে এই উপনামটি কীভাবে প্রসারিত করবেন? এটি আমাকে এটির জন্য জিজ্ঞাসা করে, এটি কীভাবে স্বয়ংক্রিয় করবেন?
জ্লাত্তো

10
@ user247077: সেক্ষেত্রে catরুট হিসাবে চলে এবং আউটপুটটি শেল দ্বারা পুনঃনির্দেশিত হয় যা মূল হিসাবে চালায় না। এটা যেমন হয় echo hi > /read/only/file
নটহাগো

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 কার্যকরভাবে বর্তমান বাফারের সামগ্রীগুলি বর্তমান ফাইলটিতে লিখুন । এর জন্য ব্যবহার করা যেতে পারে এমন আরও একটি আদেশ :dd

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

শর্টকাট হিসাবে, আপনি এই ম্যাপিংটি এতে যুক্ত করতে পারেন .vimrc:

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

উপরের সাহায্যে আপনি :w!!<Enter>ফাইলটি রুট হিসাবে সংরক্ষণ করতে টাইপ করতে পারেন ।


1
আকর্ষণীয়, :help _%আপনি যা প্রবেশ করেছেন তা :help %এনেছে তবে ব্রেস-ম্যাচিং কীটি নিয়ে আসে। আমি আন্ডারস্কোর উপসর্গটি চেষ্টা করার চিন্তা করতাম না, এটি কি ভিএম ডকুমেন্টেশনে কোনও ধরণের প্যাটার্ন? সাহায্যের সন্ধানের জন্য চেষ্টা করার মতো অন্য কোনও 'বিশেষ' জিনিস রয়েছে কি?
ডেভিড পোপ

2
@ ডেভিড: helpএকটি ট্যাগে কমান্ডটি লাফিয়ে। আপনি উপলব্ধ ট্যাগ দেখতে পারেন :h help-tags। আপনি :h cmdline<Ctrl-D>:h cmdline<Tab>wildmode
ম্যাচের

1
cmap w!! w !sudo tee % > /dev/nullএই কাজটি করতে আমার আমার .vimrc ফাইলটি ব্যবহার করতে হয়েছিল। হয় %উপরে উত্তর ভুল? (এখানে কোনও
ভিম

@ ডিএমএফএল হ্যাঁ, এটি। উত্তরের কমান্ডটি ফলস্বরূপ প্রকাশিত হবে sudo tee > /dev/null /path/to/current/fileযা সত্যিকার অর্থে উপলব্ধি করে না। (এটি সম্পাদনা করতে যাচ্ছেন)
জাজপি

1
@ জাজপি: আপনি ভুল বলেছেন। শেলগুলি প্রকৃতপক্ষে যত্ন নেয় না আপনি কমান্ড লাইনে কোথায় ফাইল পুনর্নির্দেশ করেন।
ইউজিন ইয়ারমশ

19

এটিও ভাল কাজ করে:

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

এটি @ নাথান লং-এর মন্তব্যে অনুপ্রাণিত।

বিজ্ঞপ্তি :

"পরিবর্তে অবশ্যই ব্যবহার করা উচিত 'কারণ আমরা %শেল যাওয়ার আগে প্রসারিত হতে চাই ।


11
এটি কাজ করতে পারে এমন সময়ে, এটি একাধিক প্রোগ্রামে (sh এবং বিড়াল) sudo অ্যাক্সেস দেয়। অন্যান্য উদাহরণ প্রতিস্থাপন আরও নিরাপদ হতে পারে teeসঙ্গে /usr/bin/teeপথ-পরিমার্জন আক্রমণের প্রতিরোধ।
idbrii

18

:w - একটি ফাইল লিখুন।

!sudo - শেল sudo কমান্ড কল করুন।

tee- লেখার (ভিএম: ডাব্লু) কমান্ডের আউটপুট টি ব্যবহার করে পুনঃনির্দেশিত। % বর্তমান ফাইলের নাম যেমন /etc/apache2/conf.d/mediawiki.conf ছাড়া আর কিছুই নয়। অন্য কথায় টি কমান্ডটি রুট হিসাবে চালিত হয় এবং এটি স্ট্যান্ডার্ড ইনপুট নেয় এবং এটি% দ্বারা উপস্থাপন করা কোনও ফাইলে লিখুন। তবে এটি আবার ফাইল পুনরায় লোড করার জন্য অনুরোধ জানাবে (ভিমে নিজেই পরিবর্তনগুলি লোড করতে এল চাপুন):

টিউটোরিয়াল লিঙ্ক


9

স্বীকৃত উত্তরটি সমস্তটি কভার করে, তাই আমি রেকর্ডটির জন্য আমি ব্যবহৃত একটি শর্টকাটের আরও একটি উদাহরণ দেব ।

এটি আপনার etc/vim/vimrc(বা ~/.vimrc) এ যুক্ত করুন:

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

কোথায়:

  • cnoremap: ভিমকে বলে যে নিম্নলিখিত শর্টকাটটি কমান্ড লাইনে যুক্ত হতে হবে।
  • w!!: শর্টকাট নিজেই।
  • execute '...': একটি কমান্ড যা নিম্নলিখিত স্ট্রিং কার্যকর করে।
  • silent!: নিঃশব্দে এটি চালান
  • write !sudo tee % >/dev/null: ওপি প্রশ্ন, NULLক্লিন কমান্ড তৈরি করতে বার্তাগুলির পুনঃনির্দেশ যুক্ত করেছে
  • <bar> edit!: এই কৌশলটি হ'ল কেকের চেরি: এটি editবাফারটি পুনরায় লোড করার নির্দেশ দেয় এবং তারপরে বাফার পরিবর্তিত বার্তাগুলি এড়ানো যায় । এখানে দুটি কমান্ড পৃথক করার <bar>জন্য পাইপ চিহ্নটি কীভাবে লিখবেন ।

আশা করি এটা সাহায্য করবে. অন্যান্য সমস্যার জন্যও দেখুন:


নীরব! পাসওয়ার্ড প্রম্পটটি অক্ষম করে ফেলেছে যাতে আপনি এটি দেখতে না পান
অ্যান্ডি রে

7

আমি "ওপস আমি sudoনিজের ফাইলটি খোলার সময় লিখতে ভুলে গেছি" ইস্যুতে অন্য পদ্ধতির পরামর্শ দিতে চাই :

একটি পাওয়ার পরিবর্তে permission deniedএবং টাইপ করার পরিবর্তে, :w!!শর্তসাপেক্ষে vimকমান্ড থাকা sudo vimফাইলের মালিকের হয়ে থাকলে আমি এটি আরও মার্জিত বলে মনে করি root

এটি কার্যকর করা যেমন সহজ (আরও বেশি মার্জিত বাস্তবায়নও হতে পারে, আমি স্পষ্টত কোনও বাশ-গুরু নই):

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ছোট ফাইলগুলি ব্যবহার করি )

তবে আমি দেখতে পেয়েছি এটি একটি আরও ভাল ডেভ ব্যবহারকারীর অভিজ্ঞতা নিয়ে আসে , যা ব্যবহারের সময় আইএমএইচও ভুলে যাওয়ার ঝোঁক bash। :-)


5
শুধু সচেতন থাকুন যে এটি অনেক কম ক্ষমাশীল। ব্যক্তিগতভাবে, আমার বেশিরভাগ ভুল হ'ল মূ .় ভুল। সুতরাং আমি যখন মাথা ঘুরে দাঁড়াতে পছন্দ করি যখন আমি এমন কিছু করি যা বোকা এবং ফলস্বরূপ উভয়ই হতে পারে। এটি অবশ্যই পছন্দের বিষয়, তবে বিশেষাধিকারের কাজটি একটি বিবেকবান কাজ হতে হবে। এছাড়াও: আপনি ": ডব্লু !!" হিসাবে এটি এতবার অভিজ্ঞতা হলে নিঃশব্দে অটো sudo (তবে কেবলমাত্র মালিক = মূল) যদি বিরক্ত করার পক্ষে যথেষ্ট; আপনি আপনার বর্তমান কর্মপ্রবাহ পরীক্ষা করতে চাইতে পারেন।
পায়েেন

আকর্ষণীয় মন্তব্য, যদিও কেউ সচেতন হবে কারণ যখন ফাইলটি rootপাসওয়ার্ডের অনুসন্ধানের সাথে খোলা হচ্ছে ।
অগাস্টিন রিডিংগার

আহ! পার্থক্য আছে। এটি নির্ভর করে যে sudo ব্যবহারকারীর "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-askpasssudo পাসওয়ার্ড জিজ্ঞাসা করে একটি ডায়ালগ খুলবে ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.