سؤال

وكيف يمكنني إطلاق التطبيق والتقاط الإخراج عبر المعياري وربما ستدير؟

وأنا أكتب نظام بناء الآلي وأنا بحاجة لالتقاط الإخراج إلى تحليل. أود أن تحديث الريبو إس والاستيلاء على رقم المراجعة حتى أتمكن من نقل الملفات في autobuild / revNumber / في حال نجاحها. وأود أيضا لبناء باستخدام جعل وتحميل النص الترجمة لخدمة بلدي للجميع لرؤية التحذيرات والأخطاء على بناء الفاشلة.

وأنا لا يمكن العثور على وظيفة system()، ولكنني وجدت وظيفة CreateProcess() على MSDN. وأنا قادرة على إطلاق ما أحتاج لكن ليس لدي أي فكرة عن كيفية التقاط ستدير والمعياري. ألاحظ عملية تطلق على حدة، إلا أن تعيين نقطة توقف وتبقى بلادي التطبيق المغادر الذي هو بعد ذلك سوف تبقي كل نص في بلدي إطار وحدة التحكم التطبيق. وأود أن تحتاج أيضا إلى الانتظار حتى جميع العمليات النهائية ومن ثم مسح البيانات التي أنتجت للقيام بأي عمليات إضافية أحتاج. كيف أفعل أي شيء من هذا؟

هل كانت مفيدة؟

المحلول

في قذائف حقيقية (وهذا يعني، وليس قذائف البحر - أعني، ليس في C شل أو مشتقاته)، ثم:

program arg1 arg2 >/tmp/log.file 2>&1

وهذا يعمل البرنامج مع الحجج معينة، وإعادة توجيه المعياري ل/tmp/log.file. تدوين (<ديل> الهيروغليفي ) "2>&1" في نهاية يرسل ستدير (ملف اصف 2) إلى نفس المكان الذي المعياري (ملف واصف 1) يجري. لاحظ أن تسلسل العمليات هو المهم. إذا كنت عكس ثم الخطأ المعياري سوف تذهب إلى حيث الإخراج القياسي كان على وشك، وسيتم توجيه الانتاج ثم القياسي (ولكن ليس الخطأ المعياري) إلى الملف.

واختيار اسم الملف المعروض هو السيئ لأسباب عديدة - يجب أن تسمح للمستخدم لاختيار الدليل، وربما ينبغي أن تتضمن معرف العملية أو الطابع الزمني في اسم الملف

LOG=${TMPDIR:-/tmp}/log.$$.$(date +%Y%m%d-%H%M%S)
program arg1 arg2 >$LOG 2>&1

في C ++، يمكنك استخدام وظيفة system() (الموروثة من C) لتشغيل العمليات. إذا كنت بحاجة إلى معرفة اسم الملف في برنامج C ++ (المعقول)، ثم تولد الاسم في برنامج (strftime() هو صديقك) وإنشاء سلسلة الأمر مع أن اسم الملف. (الدقيق للكلمة، تحتاج أيضا getenv() للحصول على $ TMPDIR، وgetpid() وظيفة POSIX للحصول على معرف العملية، وبعد ذلك يمكنك محاكاة شيل من سطرين (على الرغم من PID استخدامها سيكون من C ++ برنامج، وليس قذيفة أطلقت ).

هل يمكن بدلا من استخدام وظيفة POSIX popen(). كنت قد تشمل "2>&1" التدوين في سلسلة القيادة التي تقوم بإنشائها لإرسال الخطأ المعياري الأمر إلى نفس المكان كما يقول الإخراج القياسي، ولكنك لن تحتاج إلى ملف مؤقت:

FILE *pp = popen("program arg1 arg2 2>&1", "r");

وبعد ذلك يمكنك قراءة قبالة تيار الملف. لست متأكدا ما اذا كانت هناك وسيلة نظيفة لتعيين تيار ملف C إلى C ++ istream. هناك على الأرجح.

نصائح أخرى

وتحتاج لملء هيكل STARTUP_INFO، التي لديها hStdInput، hStdOutput وhStdError. تذكر أن ترث مقابض عند CreateProcess.

/* Assume you open a file handle or pipe called myoutput */
STARTUP_INFO si_startinfo;
ZeroMemory(&si_startinfo, sizeof(STARTUP_INFO));
si_startinfo.cb = sizeof(STARTUP_INFO);
si_startinfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
si_startinfo.hStdOutput = myoutput;
si_startinfo.hStdError = myoutput;
si_startifno.dwFlags != STARTF_USEHANDLES;

PROCESS_INFORMATION pi_procinfo;
ZeroMemory(&pi_procinfo, sizeof(PROCESS_INFORMATION);

CreateProcess(NULL, cmdline, NULL, NULL, true, 0, NULL, pathname, &si_startinfo, &pi_procinfo);

وأنا لم تظهر الجوانب معالجة الأخطاء، والتي سوف تحتاج إلى القيام به. تعيين الوسيطة 5TH إلى true أن ترث المقابض. وأوضح الآخرين كيفية إنشاء أنابيب ولذا فإنني لن أكرره هنا.

ومايكروسوفت المركز الملكي ومكتبة MSDN تفعل تشمل وظيفة الجهاز وظيفة _popen.

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