لا يمكن تشغيل البرنامج التفاعلي أثناء التوصيل بالبرنامج النصي في Python
-
12-11-2019 - |
سؤال
لدي برنامج نصي بيثون يحتاج إلى استدعاء الملف المحدد $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')
بالطبع يغلق واصف ملف الإدخال القياسي، لذلك إذا كنت تنوي القراءة منه مرة أخرى بعد بدء المحرر، فمن المحتمل أن تقوم بتكرار واصف الملف الخاص به قبل إغلاقه.