আমি কীভাবে বাহ্যিকভাবে ভিমকে বন্ধ করব?


23

ধরা যাক যে আমার কাছে একটি এক্স 11 সার্ভার রয়েছে যা হ্যাং হয়ে গেছে, আমাকে এক্সটির্ম ভিম সেশন থেকে কাজটি সংরক্ষণ থেকে বিরত রাখতে হবে যা X11 সার্ভারটি নিয়ন্ত্রণ করে। (জিভিম নয়, কেবল নিয়মিত ভিম-ইন-এক্সটার্ম।

কোনও উপায় আছে যা আমি (অন্য টার্মিনাল থেকে) চলমান ভিম প্রক্রিয়াটিকে কমান্ড লাইন থেকে "সমস্ত সংরক্ষণ এবং প্রস্থান" করতে বলতে পারি? সংকেত প্রেরণ করে, বা অন্য কোনও মাধ্যমে?

আমি ভিম সোয়াপ ফাইলগুলি সম্পর্কে জানি এবং আমি কেবল ভিমকে হত্যা করতে পারি এবং সোয়াপ থেকে পুনরুদ্ধার করতে পারি। আমি জিজ্ঞাসা করছি "ক্লিনার" উপায় আছে কিনা?


6
যদি এই ভিম সেশনগুলি কোনও সার্ভার সক্ষম (যেমন gvim ডিফল্টরূপে করে) দিয়ে শুরু করা হয়, তবে আপনি এটির জন্য ভিমের ক্লায়েন্ট-সার্ভার কার্যকারিতা ব্যবহার করতে পারেন। অন্য বিকল্পটি হ'ল ভিপি প্রোগ্রামগুলিকে একটি নতুন টার্মিনালে জোর করে টিটিওয়াই বলতে হবে এবং তারপরে এগুলি বন্ধ করে দেওয়ার জন্য reptyr ব্যবহার করা যেতে পারে।
মুরু

উত্তর:


25

এই সমস্যায় সম্প্রতি দৌড়ানোর পরে (অন্য কোনও উপায়ে: ভিম একটি রিমোট সার্ভারে চলছে এবং আমি স্ক্রিনটি ভুলে গেছি), আমি উপায় খুঁজে বের করার সিদ্ধান্ত নিয়েছি।

প্রথম ধারণাটি ছিল ভিম দ্বারা ব্যবহৃত ফাইল বর্ণনাকারীদের সন্ধান এবং এটিতে লেখার চেষ্টা করা। ভিমের এফডিএস টার্মিনাল এমুলেটর দ্বারা খোলার psedoterminal এর দিকে ইঙ্গিত করেছে, স্বাভাবিকভাবেই যথেষ্ট:

$ ls -l /proc/$(pgrep -n vim)/fd/
total 0
lrwx------ 1 muru muru 64 Nov 17 01:25 0 -> /dev/pts/14
lrwx------ 1 muru muru 64 Nov 17 01:25 1 -> /dev/pts/14
lrwx------ 1 muru muru 64 Nov 17 01:25 2 -> /dev/pts/14
lrwx------ 1 muru muru 64 Nov 17 01:25 3 -> socket:[99564312]

তবে, আমার প্রাথমিক কয়েকটি প্রচেষ্টা ব্যর্থ হয়েছে:

echo '^[:wq^M' > /proc/$(pgrep -n vim)/fd/0
echo ':wq^M' > /proc/$(pgrep -n vim)/fd/0
echo ':wq^M' > /proc/$(pgrep -n vim)/fd/0
echo '^C' > /proc/$(pgrep -n vim)/fd/0
printf "%s" '^[:wqa!^M' > /proc/$(pgrep -n vim)/fd/0

^[এবং ^Mদ্বারা প্রাপ্ত হয় CtrlVEscএবং CtrlVEnterযথাক্রমে।

তারা সকলে ফলাফলগুলি টার্মিনালে প্রদর্শিত হয়েছিল (দূরবর্তী সেশনে এটি প্রয়োগ করার আগে আমি স্থানীয়ভাবে এটি পরীক্ষা করে দেখছিলাম)। আশেপাশে গুগল করে, আমি সিওডোটারমিনাল ডিভাইসে লেখার জন্য পাইথন ব্যবহার করে এই এসও পোস্টটি পেয়েছি :

#!/usr/bin/python

import sys,os,fcntl,termios
if len(sys.argv) != 3:
   sys.stderr.write("usage: ttyexec.py tty command\n")
   sys.exit(1)
fd = os.open("/dev/" + sys.argv[1], os.O_RDWR)
cmd=sys.argv[2]
for i in range(len(cmd)):
   fcntl.ioctl(fd, termios.TIOCSTI, cmd[i])
fcntl.ioctl(fd, termios.TIOCSTI, '\n')
os.close(fd)

এবং এটি একটি ইন্টারেক্টিভ পাইথন শেল দিয়ে চেষ্টা করে দেখেছে:

$ sudo python3
Python 3.5.0 (default, Sep 20 2015, 11:28:25) 
[GCC 5.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os, fcntl, termios
>>> fd = os.open('/dev/pts/14', os.O_RDWR)
>>> a = '\033:wqa!\n'
>>> for i in a: fcntl.ioctl(fd, termios.TIOCSTI, i);
... 
b'\x1b'
b':'
b'w'
b'q'
b'a'
b'!'
b'\n'
>>> 

সম্পন্ন!


1
দ্রষ্টব্য যে পাইথন স্ক্রিপ্টটির টার্মিনালটি অ্যাক্সেস করার জন্য রুট অনুমতি প্রয়োজন।
মার্টিনকুনেভ

6

আপনি যদি চালাচ্ছেন তবে আপনি বাহ্যিকভাবে ভিমে কমান্ড প্রেরণ করতে পারেন ...

ভিম সার্ভার

উদাহরণস্বরূপ, করছেন:

vim --servername vim

ভিএম "vim" নামের সাথে একটি সার্ভার চালু করবে। এটিকে দু'বার কল করুন এবং নতুন সার্ভারটি "vim1" নামে পরিচিত হবে, তিনবার কল করুন এবং এটি "vim2" হবে etc. ইত্যাদি that আপনি সম্ভবত এই আদেশের একটি উপাধি তৈরি করতে চাইতে পারেন।

উইন্ডো শিরোনাম দেখে কোনও সার্ভারের কোনও নির্দিষ্ট উদাহরণটির নামকরণ করা যেতে পারে। যখন তুমি দেখ:

[নাম নেই] + - ভিআইএম 3

সার্ভারের নাম কেস-সংবেদনশীলভাবে "ভিআইএম 3" হয় ("ভিআইএম 3" একই উদাহরণটি বোঝায়)) আপনি যদি দেখুন:

[নাম নেই] + - ভিআইএম

এর অর্থ এই নয় যে এটি "ভিআইএম" নামে একটি সার্ভার পেয়েছে। আপনি সার্ভারের নাম তালিকাভুক্ত করে সার্ভারের উপস্থিতি নিশ্চিত করতে পারেন:

vim --serverlist

তবুও, প্রশ্নটি কেবল "ভিআইএম" এর জন্য বিশেষভাবে উত্থাপিত হয়। যদি আপনি "জিভিআইএম" বা এতে সংযুক্ত একটি সংখ্যার সাথে অন্য কোনও নাম দেখতে পান তবে তার অর্থ এটি একটি সার্ভার।

কীভাবে ক্লায়েন্ট ব্যবহার করবেন

এখন, আপনার প্রশ্নের উপর, আপনি সমস্ত সংরক্ষণ করতে পারেন এবং একটি প্রদত্ত ভিআইএম উদাহরণ ছেড়ে দিয়ে, উদাহরণস্বরূপ:

vim --servername vim2 --remote-send $'\e:wqa\n'

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

আপনি যদি এখানে আপনার ক্ষেত্রে যেমন সমস্ত দৃষ্টান্তের জন্য এটি করতে চান তবে আপনি কেবল সার্ভারের তালিকার মাধ্যমে লুপ করতে পারেন:

for instance in $(vim --serverlist); do
  vim --servername $instance --remote-send $'\e:wqa\n'
done

যদি কোনও কারণে আপনার পছন্দ না হয় তবে --remote-sendআপনি এর পরিবর্তে --remote-exprএমন সুবিধা ব্যবহার করতে পারেন যা এটি ক্লায়েন্টকে ফলাফল বা ত্রুটির কারণে আউটপুট দেয়, যেমন:

$ vim --servername vim2 --remote-expr 'execute("wqa")'

E141: No file name for buffer 1

নোট করুন যে ভিমের সার্ভার কার্যকারিতা ব্যবহারের জন্য প্রয়োজনীয় যে ভিমটি +clientserverবিকল্পটি দিয়ে নির্মিত হয়েছিল ।


5

reptyrসিস্টেমের প্যাকেজ ম্যানেজার ব্যবহার করে কমান্ডটি ইনস্টল করুন , যেমন:

sudo apt install reptyr
pacman -Sy reptyr

তারপরে reptyrস্থানীয় (নতুন) টিটিতে রিমোট টিটিটি পরিবর্তন করতে কমান্ডটি ব্যবহার করুন :

ssh user@remote-hostname
ps auxw | grep -i vim
reptyr PID

কমান্ড আউটপুট PIDথেকে প্রক্রিয়া আইডি কোথায় ps

ত্রুটির পরে:

পিড 12345 এ সংযুক্তি করতে অক্ষম: অনুমতি অস্বীকার করা হয়েছে

"Ptrace স্কোপ" 0 তে পরিবর্তন করুন:

sudo su -
echo 0 > /proc/sys/kernel/yama/ptrace_scope

একবার ভিআইএম সেশনটি পুরনো অধিবেশন থেকে নতুনটিতে সরিয়ে নেওয়া হলে সংরক্ষণ করুন এবং যথারীতি প্রস্থান করুন। নোট করুন যে Enterকনসোলটি রিফ্রেশ করার জন্য আপনাকে টিপতে হতে পারে ।


0

আপনি যদি দয়া করে ভিমকে হত্যা করেন?

kill -s 15 -p [PID for Vim]

কিল-এস (সিগন্যাল) 15 কে সিগন্যার্টাম বলা হয় যা প্রক্রিয়াটি নিখুঁতভাবে নিজেকে বন্ধ করতে বলে।

ভিম ব্যবহারের পিআইডি (প্রসেস আইডি) পেতে:
ps ax | grep vim


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