আমি কী কোনও স্ক্রিন সেশনে চলমান একটি সক্রিয় প্রক্রিয়াটির STDIN কে কিছু পাঠাতে পারি?


70

আমার লিনাক্স সার্ভারে একটি স্ক্রিন সেশনের অভ্যন্তরে আমার দীর্ঘকালীন সার্ভার প্রক্রিয়া রয়েছে process এটি কিছুটা অস্থির (এবং দুঃখের সাথে আমার সফ্টওয়্যার নয় তাই আমি এটি ঠিক করতে পারি না!), তাই স্থিতিশীলতায় সহায়তা করতে আমি প্রক্রিয়াটির একটি রাতের পুনরায় আরম্ভ করতে চাই। এটিকে চমত্কারভাবে শাটডাউন করার একমাত্র উপায় হ'ল স্ক্রিন প্রক্রিয়াতে যাওয়া, এটি যে উইন্ডোটিতে চলছে তার দিকে স্যুইচ করুন এবং তার নিয়ন্ত্রণ কনসোলে স্ট্রিং "স্টপ" প্রবেশ করান।

প্রতিদিন কোনও নির্দিষ্ট সময়ে ক্রোনজব সেই স্টপ কমান্ডটি প্রেরণ করতে আমি কি করতে পারি এমন কোনও স্মার্ট রিডাইরেকশন কনট্রোশন রয়েছে?

উত্তর:


85

এই উত্তরটি সমস্যার সমাধান করে না, তবে এটি এখানেই রেখে দেওয়া হয়েছে কারণ 30+ জন লোক এটি দরকারী বলে মনে করে , অন্যথায় আমি এটি অনেক আগেই মুছে ফেলতাম

লিখুন /proc/*pid of the program*/fd/0fdসাব সব খুলে ফাইল বর্ণনাকারী রয়েছে এবং ফাইল বর্ণনাকারী 0স্ট্যান্ডার্ড ইনপুট (1 stdout- এ হল এবং 2 দ্বারা stderr) হয়।

আপনি এটি টিটিএমটিতে বার্তাগুলিতে আউটপুট ব্যবহার করতে পারেন যেখানে কোনও প্রোগ্রাম চলছে, যদিও এটি আপনাকে প্রোগ্রামটিতে নিজেই লেখার অনুমতি দেয় না।

উদাহরণ

বন্দর 1:

[ciupicri@hermes ~]$ cat
shows on the tty but bypasses cat

টার্মিনাল ২:

[ciupicri@hermes ~]$ pidof cat
7417
[ciupicri@hermes ~]$ echo "shows on the tty but bypasses cat" > /proc/7417/fd/0

3
@ জেমস ল্যারি: তারপরে প্রোক (5) এবং প্রো.কম। দেখুন
ক্রিশ্চিয়ান সিউপিতু

2
আপনি যতটা ভাবছেন তা +2 নির্বিশেষে, শেখার জন্য আরও বেশি কিছু আছে :) চটজলদি।
ট্রয়য়েঞ্জেল

3
যদিও সচেতন থাকুন যে প্রোডাক্ট fd কেবল স্টিডিনের উত্স হিসাবে ব্যবহৃত হয় তা পুনর্নির্দেশ করে। আপনার উদাহরণস্বরূপ, আপনি যদি টার্মিনাল 1 এ কিছু প্রবেশ করেন তবে এটি আবার মুদ্রণ করবে (এটি বিড়ালদের কাছে পাঠানো হবে এবং বিড়াল এটি প্রিন্ট করে), ফলস্বরূপ আপনি এটি দুটিবার দেখতে পাচ্ছেন। অন্যদিকে আপনি যদি fd / 0 তে কিছু পাঠান তবে এটি কনসোলে প্রেরণ করা হবে তবে বিড়ালের জন্য নয়, এবং কেবল একবার প্রদর্শিত হবে। যেমন বিড়াল কেবলমাত্র এই উদাহরণটির সাথে আবার ইনপুট প্রিন্ট করে আপনি সত্যই দেখতে পারবেন না যে আপনার ইনপুট বা আউটপুট প্রিন্ট হচ্ছে কিনা, এইভাবে এই ভুল ধারণাটি। / এফডি / 0 পয়েন্ট কনসোল / পিটিএসে; দেখতে ls -l /proc/7417/fd/0
কিসাকি

4
বাস্তব-বিশ্বের উদাহরণ: আমি gphoto2 --get-all-ফাইল শুরু করেছি এবং এটি 100 বার একটি নিশ্চিতকরণ চেয়েছে। আমি যখন "y"> / proc / PID / fd / 0 প্রতিধ্বনিত করি, gphoto2 অগ্রসর হয় না, তবে, "y" টার্মিনালে মুদ্রিত হয়।
থারস্টেন স্টার্ক

2
@ থারস্টেন স্টার্ক, আমি জানি, সে কারণেই আমি এই নোটটি যুক্ত করেছি। আপনি কেবলমাত্র টার্মিনালের সাথে সম্পর্কিত ডিভাইস ফাইলে লিখছেন যেখানে gphoto2 চালিত হয় (উদাহরণস্বরূপ /dev/pts/19), yঅক্ষরটি অ্যাপ্লিকেশনটিতে পৌঁছায় না। আপনি যখন লিখুন (1) কমান্ডটি ব্যবহার করেন তখন যা ঘটে তা একই রকম । যাইহোক, হয় আমার অন্য উত্তর বা এক্সডটুলের মতো গ্রাফিকাল অটোমেশন সরঞ্জাম ব্যবহার করে দেখুন
ক্রিশ্চিয়ান সিউপিতু

36

স্ক্রিন ভিত্তিক সমাধান

সার্ভারটি এভাবে শুরু করুন:

# screen -d -m -S ServerFault tr a-z A-Z # replace with your server

স্ক্রিনটি বিচ্ছিন্ন মোডে শুরু হবে, তাই আপনি কী চলছে তা দেখতে চাইলে চালান:

# screen -r ServerFault

সার্ভারটি এটির মতো নিয়ন্ত্রণ করুন:

# screen -S ServerFault -p 0 -X stuff "stop^M"
# screen -S ServerFault -p 0 -X stuff "start^M"
# screen -S ServerFault -p 0 -X stuff "^D" # send EOF

(এই উত্তরটি ইউনিক্স এবং লিনাক্স ভাইবোন সাইট থেকে আলাদা হওয়া স্ক্রিনে পাঠ্য ইনপুট প্রেরণের উপর ভিত্তি করে )

পরামিতিগুলির ব্যাখ্যা :

-d -m
   Start screen in "detached" mode. This creates a new session but doesn't
   attach to it.  This is useful for system startup scripts.
-S sessionname
   When creating a new session, this option can be used to specify a meaningful
   name for the session.
-r [pid.tty.host]
-r sessionowner/[pid.tty.host]
   resumes a detached screen session.
-p number_or_name|-|=|+
   Preselect a window. This is useful when you want to reattach to a specific
   window or you want to send a command via the "-X" option to a specific
   window.
-X
   Send the specified command to a running screen session e.g. stuff.

স্টাফ [স্ট্রিং]

   Stuff the string string in the input  buffer of the current window.
   This is like the "paste" command but with much less overhead.  Without
   a parameter, screen will prompt for a string to stuff.

tmux ভিত্তিক সমাধান

সার্ভারটি এভাবে শুরু করুন:

# tmux new-session -d -s ServerFault 'tr a-z A-Z' # replace with your server

tmux বিচ্ছিন্ন মোডে শুরু হবে, সুতরাং যদি আপনি কী দেখতে চান তা চালনা করুন:

# tmux attach-session -t ServerFault

সার্ভারটি এটির মতো নিয়ন্ত্রণ করুন:

# tmux send-keys -t ServerFault -l stop
# tmux send-keys -t ServerFault Enter
# tmux send-keys -t ServerFault -l start
# tmux send-keys -t ServerFault Enter
# tmux send-keys -t ServerFault C-d # send EOF

পরামিতিগুলির ব্যাখ্যা :

 new-session [-AdDP] [-c start-directory] [-F format] [-n window-name] [-s
         session-name] [-t target-session] [-x width] [-y height]
         [shell-command]
         Create a new session with name session-name.

         The new session is attached to the current terminal unless -d is
         given.  window-name and shell-command are the name of and shell
         command to execute in the initial window.  If -d is used, -x and
         -y specify the size of the initial window (80 by 24 if not
         given).

 send-keys [-lR] [-t target-pane] key ...
               (alias: send)
         Send a key or keys to a window.  Each argument key is the name of
         the key (such as `C-a' or `npage' ) to send; if the string is not
         recognised as a key, it is sent as a series of characters.  The
         -l flag disables key name lookup and sends the keys literally.

4

এটি শুরু করার চেষ্টা করুন:

# screen
# cd /path/to/wd
# mkfifo cmd
# my_cmd <cmd
C-A d

এবং এই হত্যার জন্য:

# cd /path/to/wd
# echo "stop" > cmd
# rm cmd

3
এটি ভাল তবে প্রোগ্রামটি চলাকালীন অন্য কমান্ডগুলি প্রেরণ করতে না পারার অসুবিধা হতে পারে। প্রোগ্রামটি স্টিডিতে ইওএফ হিট করার পরে echo "xxx" > cmdযদি বন্ধ হয়ে যায় তবে প্রথমে প্রোগ্রামটি বন্ধ হয়ে যাবে (কারণ পাইপটি বন্ধ থাকবে)। যদিও কিছু প্রোগ্রাম rewind(3)ইওএফ-এর মুখোমুখি হয় তখন তাদের স্টিডিন পুনরায় খোলার জন্য যথেষ্ট স্মার্ট are
ক্রিশ্চিয়ান সিউপিতু

2

screenইউটিলিটি বা অন্য কোনও অভিনব ইউটিলিটি চালনা না করে চলমান প্রক্রিয়াতে ইনপুট পাঠানো সম্ভব । এবং প্রক্রিয়াটির 'স্ট্যান্ডার্ড ইনপুট "ফাইলটিতে এই ইনপুট পাঠ্য পাঠানোর মাধ্যমে এটি করা যায় /proc/PID#/fd/0

তবে প্রক্রিয়াটি পড়ার জন্য ইনপুট পাঠ্যটি একটি বিশেষ উপায়ে প্রেরণ করা দরকার needs নিয়মিত ফাইল writeপদ্ধতির মাধ্যমে ইনপুট পাঠ্য পাঠানো প্রক্রিয়াটির ফলে পাঠ্যটি গ্রহণ করবে না। এর কারণ এটি করা কেবলমাত্র সেই "ফাইল" এ যুক্ত হবে তবে বাইটগুলি পড়তে প্রক্রিয়াটি ট্রিগার করবে না।

বাইটগুলি পড়তে প্রক্রিয়াটি ট্রিগার করতে, প্রতিটি একক বাইট প্রেরণের জন্য IOCTLটাইপের একটি অপারেশন করা প্রয়োজন TIOCSTI। এটি বাইটটি প্রক্রিয়াটির 'স্ট্যান্ডার্ড ইনপুট কাতারে রাখবে।

সি, পার্ল এবং পাইথনের কয়েকটি উদাহরণ সহ এটি এখানে আলোচনা করা হয়েছে:

https://unix.stackexchange.com/questions/48103/construct-a-command-by-putting-a-string-into-a-tty/48221

-

সুতরাং প্রায় 9 বছর আগে জিজ্ঞাসিত মূল প্রশ্নের উত্তর দিতে, ক্রোন জবটির জন্য কিছু অন্যান্য ছোট্ট ইউটিলিটি স্ক্রিপ্ট / প্রোগ্রাম চালানো দরকার যা অন্য প্রশ্নগুলির জন্য লোকেরা লিখেছিলেন, যা সেই সার্ভার প্রক্রিয়াতে স্টপ "স্টপ \ n" প্রেরণ করবে প্রশ্নে, IOCTLটাইপের একটি অপারেশনের মাধ্যমে 5 টি বাইটের প্রত্যেককে প্রেরণ করে TIOCSTI

অবশ্যই এটি কেবলমাত্র সেই সিস্টেমগুলিতে কাজ করবে যা TIOCSTI IOCTLঅপারেশন প্রকারকে সমর্থন করে (যেমন লিনাক্স), এবং কেবলমাত্র rootব্যবহারকারী অ্যাকাউন্ট থেকে, কারণ এই "ফাইলগুলি" এর অধীনে /proc/"মালিকানাধীন" রয়েছে root


1

যদি এটি কাউকে সহায়তা করে:
আমারও একই সমস্যা ছিল এবং আমি যে প্রক্রিয়াটি ব্যবহার করছিলাম সেটির অধীনে ছিল না screenবা tmux, আমাকে অন্যরকম পদ্ধতির গ্রহণ করতে হয়েছিল।

আমি সংযুক্ত gdbকরার xtermযে আমার প্রক্রিয়ায় চলমান ছিল, এবং ব্যবহৃত call write(5, "stop\n", 5)থেকে gdbমাস্টার Pty ফাইল বর্ণনাকারী লিখতে।
কোন ফাইলের বর্ণনাকারী ডেটা প্রেরণ /proc/<pid>/fdকরবেন /dev/ptmxএবং এটি দুটি বিকল্পের মধ্যে পরীক্ষা এবং ত্রুটি (উভয় ম্যাচের ফাইলের বর্ণনকারীকে আমার স্ট্রিং প্রেরণ করলে কোনও ক্ষতি হবে না বলে মনে করে) প্রেরণ করতে হবে I

সম্পাদনা

এটা প্রমাণিত যে xtermপ্রক্রিয়া আমি সঙ্গে উত্পন্ন হওয়া যায়নি সংযুক্ত ছিল spawn-new-terminal() xtermএকটি keybinding থেকে অ্যাকশন, এবং দ্বিতীয় ptmxফাইল বর্ণনাকারী খোলা কেবল ছিল ptmxপিতা বা মাতা এর xtermপ্রক্রিয়া যা বন্ধ হয়নি।
সুতরাং ট্রায়াল এবং ত্রুটি কলগুলি অন্যান্য টার্মিনালে আউটপুট প্রেরণ করেছিল।
বেশিরভাগ xtermপ্রক্রিয়াতে দুটি ptmxফাইল বর্ণনাকারী থাকে না।

শেষ সম্পাদনা

এটি কার্যকরভাবে সেই স্ট্রিংটি টার্মিনালে টাইপ করেছিল এবং তাই এটি এর অধীনে চলমান প্রক্রিয়াটিতে প্রেরণ করে।

nb আপনার চলমান প্রক্রিয়াতে সংযুক্ত হওয়ার মতো কিছু হতে পারে you
sudo bash -c "echo 0 > /proc/sys/kernel/yama/ptrace_scope"


0

যেহেতু আমি ক্রিশ্চিয়ান সিউপিতুর (২০১০ সালের) সর্বাধিক গৃহীত উত্তরটি মন্তব্য করতে পারি না, তাই আমাকে এটির একটি পৃথক উত্তরে রেখে দিতে হবে:

এই প্রশ্নটি ইতিমধ্যে এই থ্রেডে সমাধান করা হয়েছে: https://stackoverflow.com/questions/5374255/how-to-write-data-to-existing-processs-stdin-from-extern-- প্রসেস

সংক্ষেপে:

আপনার স্টিডিনের পাইপ দিয়ে আপনার প্রক্রিয়া শুরু করতে হবে যা বর্তমান ইনপুটটি যখন লেখা হয়েছিল তখন বাধা দেয় না বা বন্ধ হয় না। এটি একটি সাধারণ অন্তহীন লুপ দ্বারা প্রয়োগ করা যেতে পারে যা প্রশ্নে প্রক্রিয়াটিতে পাইপ করা হবে:

$ (while [ 1 ]; do sleep 1; done) | yourProgramToStart

আমি নিশ্চিত করতে পারি যে পাইপ খোলার জন্য ক্রিশির ভিন্ন উপায় যা আমার ক্ষেত্রে কাজ করছে না। প্রদর্শিত সমাধানটি পরিবর্তে কাজ করেছিল।

তারপরে এটির নির্দেশাবলী প্রেরণের জন্য আপনি প্রক্রিয়াটির ... / fd / 0 ফাইলটিতে লিখতে পারেন। কেবলমাত্র ব্যর্থতা হ'ল আপনাকে বাশ প্রক্রিয়াটিও বন্ধ করতে হবে যা সার্ভারটি বন্ধ হওয়ার পরে অবিরাম-লুপ চালাচ্ছে।

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