سؤال

ملاحظة: اعتقدت أنني كنت أستخدم Bash ، لكن /Bin /Sh مرتبط بـ /bin /dash ، والتي تواجه مشكلة Exec الغريبة.

لديّ برنامج نصي SLEST SLEST بسيط على Linux يستخدم لإطلاق عملية خادم (لم أكتبها أو أتحكم فيها) وأرغب في إخراج نص Bash Shell من PID الذي تم إطلاقه إلى pidfile.

المشكلة هي أن أمر bash-exec لا يحل محل عمليته بعملية الخادم التي تم إطلاقها!

لذا:

echo $$ | cat > /var/run/launched-server.pid

هذا لا ليس العمل لأن PID في الملف سيكون عملية Bash وليس عملية الخادم. وإذا خرجت عملية الخادم ، فقد لا تخرج Bash عن ترك البرنامج النصي الذي يطلقه عملية الإطلاق الغبية في قائمة العملية.

هل يعرف أي شخص طريقة لاستخدام Bash (أو Dash ربما؟) بحيث:

  1. هل هو ممكن؟
  2. سيكون PID لعملية خادم خادم الخادم في Pidfile الخاص بي؟
  3. تأكد من أن البرنامج النصي Bash سيموت عندما يكون الخادم الذي تم إطلاقه ولن يترك عمليات قذيفة مبهمة تتسكع في قائمة العملية؟

تحرير: هذا المقتطف من دليل مرجع باش كن مفيدًا ...

exec
           exec [-cl] [-a name] [command [arguments]]

إذا تم توفير الأمر ، فإنه يحل محل الصدفة دون إنشاء عملية جديدة. إذا تم توفير خيار -L ، فإن القشرة تضع اندفاعة في بداية وسيطة Zeroth التي تم تمريرها إلى القيادة. هذا ما يفعله برنامج تسجيل الدخول. يتسبب خيار -C في تنفيذ الأمر مع بيئة فارغة. إذا تم تزويد -A ، فإن القشرة تمرر كسيطة Zeroth إلى القيادة. إذا لم يتم تحديد أي أمر ، فيمكن استخدام التوجيهات للتأثير على بيئة الصدفة الحالية. إذا لم تكن هناك أخطاء إعادة توجيه ، فإن حالة الإرجاع هي صفر ؛ وإلا فإن حالة العودة غير صفرية.


تحرير 2: هذا هو البرنامج النصي (تم تطهير):

#!/bin/sh

# this is where the server expects to run its services for Daemontools
SERVICE_DIR='/var/service';

# kill stdout, stderr, stdin
exec </dev/null
exec >/dev/null
exec 2>/dev/null

logger -ip daemon.debug -- stdout, stderr, stdin redirected to /dev/null

if [ -d $SERVICE_DIR ]; then
    # sanitized...
    logger -ip daemon.debug -- services and supervisors exited
else
    logger -ip daemon.err -- $SERVICE_DIR does not exist, exiting
    exit 1;
fi

if [ -d /var/run/pid ]; then
    echo $$ | cat > /var/run/pid/launched-server.pid
    logger -ip daemon.debug -- creating launched-server pidfile
fi

# start the server process
logger -ip daemon.info -- launching server on $SERVICE_DIR
exec /usr/local/bin/launched-server

وبعض الإخراج PS ربما يكون أكثر وضوحا؟

me@chainsaw: ~/dev $ ps ax | grep launched-server
13896 pts/1    S+     0:00 /bin/sh ./server_boot
13905 pts/1    S+     0:00 launched-server /var/service
13938 pts/2    R+     0:00 grep --color=auto launched-server
هل كانت مفيدة؟

المحلول

هل يتضمن توزيعك start-stop-daemon(8)؟ أداة صغيرة مفيدة بشكل رائع ، تم بناؤها خصيصًا لبدء الشياطين من البرامج النصية Shell. (بالطبع ، تفوق الشياطين البرامج النصية للقذيفة ، لذلك قد لا تكون مباراة مثالية - فهذا يعتمد على سبب رغبتك في تفوق القشرة على الخفي.)

أو لشيء أبسط:

هل يمكن حل مشكلتك مع باش exec أمر؟ يحل محل عملية shell بأي برنامج تطلب تنفيذه:

#!/bin/bash

echo $$ > /tmp/pidfile
exec /bin/sleep 60

$ ./show_exec.sh 
[nothing happens]

وفي قذيفة أخرى:

$ cat pidfile
24686
$ ps auxw | grep 24686
sarnold  24686  0.0  0.0   9728   816 pts/1    S+   04:53   0:00 /bin/sleep 60

نصائح أخرى

أنا الآن أدرك ما حقيقة كانت المشكلة:

باستخدام #!/bin/sh لم أكن أدعو باش ، لكن داش.

Exec Dash هي قذيفة مع مشكلة exec. لو كنت قد استخدمت #!/bin/bash منذ البداية ، كان من شأنه أن يعمل كما هو متوقع.

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