सवाल क्या मैं स्क्रीन सत्र में चल रही सक्रिय प्रक्रिया के एसटीडीआईएन को कुछ पाठ भेज सकता हूं?


मेरे लिनक्स सर्वर पर एक स्क्रीन सत्र के अंदर मेरे पास एक लंबी चल रही सर्वर प्रक्रिया है। यह थोड़ा अस्थिर है (और दुख की बात है कि मेरा सॉफ़्टवेयर नहीं है इसलिए मैं इसे ठीक नहीं कर सकता!), इसलिए मैं स्थिरता में मदद के लिए प्रक्रिया के एक रात के पुनरारंभ को स्क्रिप्ट करना चाहता हूं। इसे एक शानदार शट डाउन करने का एकमात्र तरीका स्क्रीन प्रक्रिया पर जाना है, उस विंडो पर स्विच करें जिसमें वह चल रहा है, और उसके नियंत्रण कंसोल पर स्ट्रिंग "स्टॉप" दर्ज करें।

क्या कोई स्मार्ट रीडायरेक्शन contortions मैं cronjob को हर दिन एक निश्चित समय पर उस स्टॉप कमांड को भेजने के लिए कर सकता हूं?


61
2017-09-06 11:42


मूल




जवाब:


यह उत्तर समस्या का समाधान नहीं करता है, लेकिन यह यहां छोड़ा गया है क्योंकि 30+ लोगों ने इसे उपयोगी पाया है, अन्यथा मैं इसे बहुत समय पहले हटा देता।

लिखो /proc/*pid of the program*/fd/0fd उपनिर्देशिका में सभी खुली फ़ाइलों और फ़ाइल डिस्क्रिप्टर के वर्णनकर्ता शामिल हैं 0 मानक इनपुट है (1 stdout है और 2 stderr है)।

आप इसे टीटी पर आउटपुट संदेशों के लिए उपयोग कर सकते हैं जहां एक प्रोग्राम चल रहा है, हालांकि यह आपको प्रोग्राम को लिखने की अनुमति नहीं देता है।

उदाहरण

टर्मिनल 1:

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

टर्मिनल 2:

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

78
2017-09-06 12:06



@ जेम्स लॉरी: फिर एक नज़र डालें proc (5) तथा proc.txt। - Cristian Ciupitu
+2 कोई फर्क नहीं पड़ता कि आप कितना सोचते हैं, सीखने के लिए हमेशा और अधिक है :) slick। - troyengel
ध्यान रखें कि proc fd केवल stdin के स्रोत के रूप में उपयोग किए जाने वाले चीज़ों को रीडायरेक्ट करता है। आपके उदाहरण में, यदि आप टर्मिनल 1 में कुछ दर्ज करते हैं तो यह फिर से प्रिंट करेगा (यह बिल्लियों stdin और बिल्ली को प्रिंट करता है), जिसके परिणामस्वरूप आप इसे दो बार देखते हैं। दूसरी तरफ यदि आप एफडी / 0 को कुछ भेजते हैं तो इसे कंसोल पर भेजा जाएगा, लेकिन बिल्ली के लिए नहीं, और इस प्रकार केवल एक बार प्रदर्शित किया जाएगा। जैसे ही बिल्ली इस उदाहरण के साथ फिर से इनपुट प्रिंट करती है, आप वास्तव में नहीं देख सकते कि आपका इनपुट या आउटपुट मुद्रित किया जा रहा है, इस प्रकार यह गलतफहमी। कंसोल / अंक के लिए / fd / 0 अंक; देख ls -l /proc/7417/fd/0। - Kissaki
असली दुनिया का उदाहरण: मैंने gphoto2 --get-all-files शुरू कर दी है और यह 100 बार पुष्टि की मांग करती है। जब मैं "y"> / proc / pID / fd / 0 गूंजता हूं, gphoto2 आगे नहीं बढ़ता है, हालांकि, "y" टर्मिनल में मुद्रित होता है। - Thorsten Staerk
@ThorstenStaerk, मुझे पता है, यही कारण है कि मैंने उस नोट को जोड़ा। आप केवल उस टर्मिनल से संबंधित डिवाइस फ़ाइल पर लिख रहे हैं जिस पर gphoto2 चलता है (उदा। /dev/pts/19), द y चरित्र स्वयं एप्लिकेशन तक नहीं पहुंचता है। यह तब होता है जब आप इसका उपयोग करते हैं लिखने (1) आदेश। वैसे भी, या तो मेरा अन्य उत्तर या एक ग्राफिकल स्वचालन उपकरण जैसे कोशिश करें xdotool। - Cristian Ciupitu


स्क्रीन आधारित समाधान

इस तरह सर्वर शुरू करें:

# 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 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.

34
2017-10-19 01:08





शुरू करने के लिए इसे आजमाएं:

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

और यह मारने के लिए:

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

4
2017-09-06 12:03



यह अच्छा है, लेकिन प्रोग्राम चल रहा है, जबकि अन्य आदेश भेजने में सक्षम नहीं होने का नुकसान हो सकता है। यदि प्रोग्राम स्टॉप पर ईओएफ हिट करता है तो पहले बंद हो जाता है echo "xxx" > cmd कार्यक्रम बंद हो जाएगा (क्योंकि पाइप बंद हो जाएगा)। हालांकि कुछ कार्यक्रम फिर से खोलने के लिए पर्याप्त स्मार्ट हैं (rewind(3)) जब वे ईओएफ का सामना करते हैं तो उनके stdin। - Cristian Ciupitu


अगर यह किसी की मदद करता है:
मुझे एक ही समस्या थी, और जिस प्रक्रिया का मैं उपयोग कर रहा था वह नीचे नहीं था screen या tmux, मुझे एक अलग दृष्टिकोण लेना पड़ा।

मैं संलग्न हुआ gdb को xterm कि मेरी प्रक्रिया में चल रहा था, और इस्तेमाल किया call write(5, "stop\n", 5) से gdb मास्टर पीटीआई फाइल डिस्क्रिप्टर को लिखने के लिए।
मुझे पता चला कि किस फाइल डिस्क्रिप्टर को डेटा भेजकर डेटा भेजना है /proc/<pid>/fd एक लिंक के लिए /dev/ptmx और फिर दो विकल्पों के बीच परीक्षण और त्रुटि (दोनों मिलान फ़ाइल डिस्क्रिप्टरों को मेरी स्ट्रिंग भेजना कोई नुकसान नहीं पहुंचा)।

संपादित करें

यह पता चला कि xterm जिस प्रक्रिया से मैंने जुड़ा था, उसके साथ पैदा हुआ था spawn-new-terminal()  xterm एक कीबाइंडिंग से कार्रवाई, और दूसरा ptmx फाइल डिस्क्रिप्टर ओपन बस था ptmx माता-पिता का xterm प्रक्रिया जो बंद नहीं हुई थी।
इसलिए परीक्षण और त्रुटि कॉल ने उस दूसरे टर्मिनल को आउटपुट भेजा था।
अधिकांश xterm प्रक्रियाओं में दो नहीं हैं ptmx फाइल डिस्क्रिप्टर।

अंत संपादित करें

इसने टर्मिनल में उस स्ट्रिंग को प्रभावी ढंग से टाइप किया, और इसलिए इसे इसके तहत चल रही प्रक्रिया के साथ भेजा।

N.B. आपको किसी ऐसी प्रक्रिया के साथ चलने की प्रक्रिया को जोड़ने की अनुमति देनी पड़ सकती है
sudo bash -c "echo 0 > /proc/sys/kernel/yama/ptrace_scope"


1
2017-12-31 09:42