لا يمكن تشغيل البرنامج التفاعلي أثناء التوصيل بالبرنامج النصي في Python

StackOverflow https://stackoverflow.com/questions/5986544

سؤال

لدي برنامج نصي بيثون يحتاج إلى استدعاء الملف المحدد $EDITOR أو $VISUAL.عندما يتم استدعاء البرنامج النصي Python بمفرده، أكون قادرًا على تشغيل ملف $EDITOR دون أي عوائق، ولكن في اللحظة التي أقوم فيها بتوصيل شيء ما إلى نص بايثون، فإن $EDITOR غير قادر على إطلاق.الآن، أنا أستخدم النانو الذي يظهر

تم استلام SIGUP أو SIGTERM

كل مرة.ويبدو أن نفس المشكلة الموصوفة هنا.

sinister:Programming [1313]$ echo "import os;os.system('nano')" > "sample.py" 
sinister:Programming [1314]$ python sample.py
# nano is successfully launched here.
sinister:Programming [1315]$ echo "It dies here." | python sample.py 
Received SIGHUP or SIGTERM

Buffer written to nano.save.1

يحرر:إيضاح؛داخل البرنامج، لا أقوم بالتوجيه إلى المحرر.رمز على النحو التالي:

editorprocess = subprocess.Popen([editor or "vi", temppath])
editorreturncode = os.waitpid(editorprocess.pid, 0)[1]
هل كانت مفيدة؟

المحلول

عندما تقوم بتوصيل شيء ما إلى عملية ما، يتم توصيل الأنبوب بالإدخال القياسي لتلك العملية.وهذا يعني أن مدخلاتك الطرفية لن تكون متصلة بالمحرر.يتحقق معظم المحررين أيضًا مما إذا كان الإدخال القياسي الخاص بهم هو محطة طرفية (com.isatty)، وهو أنبوب ليس كذلك؛وإذا لم تكن محطة، فسوف يرفضون البدء.في حالة nano, ، يبدو أن هذا يؤدي إلى خروجه بالرسالة التي قمت بتضمينها:

% echo | nano
Received SIGHUP or SIGTERM

ستحتاج إلى توفير المدخلات إلى نص بايثون الخاص بك بطريقة أخرى، مثلًا عبر ملف، إذا كنت تريد أن تكون قادرًا على تمرير مدخلاته القياسية إلى محرر طرفي.

لقد أوضحت الآن سؤالك، أنك لا تريد عملية بايثون stdin المرفقة بالمحرر، يمكنك تعديل الكود الخاص بك على النحو التالي:

editorprocess = subprocess.Popen([editor or "vi", temppath],
                                 stdin=open('/dev/tty', 'r'))

نصائح أخرى

الحالة المحددة ل find -type f | vidir - يتم التعامل معها هنا:

foreach my $item (@ARGV) {
    if ($item eq "-") {
        push @dir, map { chomp; $_ } <STDIN>;
        close STDIN;
        open(STDIN, "/dev/tty") || die "reopen: $!\n";
    }

يمكنك إعادة إنشاء هذا السلوك في بايثون أيضًا:

#!/usr/bin/python

import os
import sys

sys.stdin.close()
o = os.open("/dev/tty", os.O_RDONLY)
os.dup2(o, 0)
os.system('vim')

بالطبع يغلق واصف ملف الإدخال القياسي، لذلك إذا كنت تنوي القراءة منه مرة أخرى بعد بدء المحرر، فمن المحتمل أن تقوم بتكرار واصف الملف الخاص به قبل إغلاقه.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top