تحليل proc/pid/cmdline للحصول على معلمات الوظيفة

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

  •  05-07-2019
  •  | 
  •  

سؤال

أحاول استخراج المعلمة التي تم استدعاء التطبيق بها باستخدام البيانات الموجودة داخل cmdline.

إذا بدأت مثيل تطبيق مثل هذا:

تطبيق 1 2

ثم قطط cmdline الخاص بـ myapp وسأرى شيئًا مثل myapp12.

كنت بحاجة لاستخراج هذه القيم واستخدمت هذا الجزء من التعليمات البرمجية للقيام بذلك


pid_t proc_id = getpid();

sprintf(buf,"/proc/%i/cmdline",proc_id);

FILE * pFile;
pFile = fopen (buf,"r");
if (pFile!=NULL)
{
    fread(buf,100,100,pFile);
    cout << "PID " << proc_id << endl;
    string str = buf;
    cout << buf << endl;
    size_t found=str.find_last_of("/\\");
    cout << " file: " << str.substr(found+1) << endl;

    fclose (pFile);
}

ولكن ما أحصل عليه هو اسم التطبيق فقط ولا توجد معلمات ...


تم نسخ التحديث من الإجابة:

حسنًا، يبدو أن سؤالي الآن هو كيف أقرأ ملف cmdline دون أن يتوقف عند أول حرف NULL...

fopen(cmdline, "rb")

لا يفعل أي شيء آخر لذلك...

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

المحلول

جميع معلمات سطر الأوامر (ما يمكن أن يأتي من خلال ملف argv[] array) هي في الواقع سلاسل مفصولة بقيمة خالية /proc/XXX/cmdline.

abatkin@penguin:~> hexdump -C /proc/28460/cmdline
00000000  70 65 72 6c 00 2d 65 00  31 20 77 68 69 6c 65 20  |perl.-e.1 while |
00000010  74 72 75 65 00                                    |true.|

وهذا يفسر لماذا عندما cat'إد cmdline لقد كانوا جميعًا "عالقين" معًا (cat تجاهل الأحرف NULL غير الصالحة) ولماذا cout توقف بعد وسيطة سطر الأوامر الأولى (اسم العملية) لأنه كان يعتقد أن اسم العملية عبارة عن سلسلة منتهية بقيمة خالية وتوقف عن البحث عن المزيد من الأحرف في تلك المرحلة.

معالجة وسيطات سطر الأوامر

لمعالجة وسيطات سطر الأوامر، لديك خياران.إذا كنت تريد فقط سطر الأوامر بأكمله كسلسلة عملاقة واحدة، فقم بالتكرار من 0 إلى (numRead - 2) (أين numRead هو عدد الأحرف المقروءة) واستبدل أي بايتات فارغة (curByte == 0) مع المساحات.ثم تأكد فقط من تعيين الحرف الأخير ليكون بايت NULL أيضًا (في حالة اقتطاع الأشياء بسبب المخزن المؤقت ذي الحجم الثابت).

إذا كنت تريد بدلاً من ذلك مصفوفة تحتوي على جميع الوسائط، فيجب أن تكون أكثر إبداعًا.سيكون أحد الخيارات هو التكرار من 0 إلى (numRead - 1) ويمكن لجميع البايتات الفارغة التي تجدها.ثم قم بتخصيص مجموعة من char*بهذا الطول.ثم قم بالتكرار عبر سطر الأوامر، مع تحديد بداية كل سلسلة (على سبيل المثال:البايت الأول في المصفوفة، بالإضافة إلى كل بايت يتبع بايت NULL) إلى عناصر متتالية من المصفوفة char*'س.

اعلم فقط أنه بما أنك تقرأ في مخزن مؤقت ذي حجم ثابت، فسيتم اقتطاع أي شيء يتجاوز هذا المخزن المؤقت.لذا تذكر أنه مهما فعلت، ربما تحتاج إلى التأكد يدويًا من أن نهاية السلسلة الأخيرة تنتهي بـ NULL، وإلا فإن معظم وظائف معالجة السلسلة لن تعرف أين تنتهي السلسلة وستستمر في العمل إلى الأبد.

نصائح أخرى

و/usr/bin/strings /proc/1337/cmdline عادة القيام بهذه المهمة بالنسبة لي.

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