كيفية الحصول على PID من العملية التي يتم ضخها إلى عملية أخرى في باش؟

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

  •  22-07-2019
  •  | 
  •  

سؤال

واني اسعى الى تطبيق خادم سجل بسيط في باش. ينبغي أن تأخذ ملف كمعلمة وخدمتها على منفذ مع أداة netcat.

( tail -f $1 & ) | nc -l -p 9977

ولكن المشكلة هي أنه عندما إنهاء أداة netcat، يتم ترك الذيل وراء تشغيل. (توضيح: إذا كنت لا مفترق عملية ذيل أنها ستستمر في تشغيل إلى الأبد حتى ينهي أداة netcat)

إذا كنت تعرف بطريقة أو بأخرى PID من الذيل ثم أتمكن من قتله بعد ذلك.
من الواضح، وذلك باستخدام $! سيعود PID من أداة netcat.

وكيف يمكنني الحصول على PID لعملية الذيل؟

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

المحلول

PID

والكتابة الذيل إلى ملف واصف 3، ومن ثم استيلاء عليها من هناك.

( tail -f $1 & echo $! >&3 ) 3>pid | nc -l -p 9977
kill $(<pid)

نصائح أخرى

وثمة خيار آخر: استخدام إعادة توجيه إلى المستوى الفرعي. هذا يغير الترتيب الذي تم تشغيلها العمليات الخلفية، لذلك $! يعطي PID عملية tail.

tail -f $1 > >(nc -l -p 9977) &
wait $!

وماذا عن هذا:

jobs -x echo %1

و%1 هو لأول وظيفة في السلسلة، %2 لمدة ثانية، الخ jobs -x يستبدل محدد العمل مع PID.

وهذا يعمل بالنسبة لي (SLES لينكس):

tail -F xxxx | tee -a yyyy &
export TAIL_PID=`jobs -p`
# export TEE_PID="$!"

وقال إن خدعة ps|grep|kill المذكورة في هذا الموضوع لا تعمل إذا كان يمكن للمستخدم تشغيل البرنامج النصي لمدة سنتين "الحالات" على نفس الجهاز.

وjobs -x echo %1 لم تنجح بالنسبة لي (الصفحة الرجل لا وجود العلم -x) ولكن أعطاني فكرة لمحاولة jobs -p.

وربما يمكن استخدام FIFO ، بحيث يمكنك التقاط معرف المنتج من العملية الأولى ، على سبيل المثال:

FIFO=my_fifo

rm -f $FIFO
mkfifo $FIFO

tail -f $1 > $FIFO &
TAIL_PID=$!

cat $FIFO | nc -l -p 9977

kill $TAIL_PID

rm -f $FIFO

وأخيرا، لقد تمكنت من العثور على عملية ذيل باستخدام ps. وبفضل هذه الفكرة من ennuikiller.

ولقد استخدمت ps على البقرى ذيل من وسائط وقتله. انه نوع من الإختراق لكنه يعمل. :)

إذا أن تجد طريقة أفضل يرجى حصة.

وهنا هو السيناريو الكامل:
(يمكن الاطلاع على أحدث الإصدارات هنا: http://docs.karamatli.com/dotfiles/bin/ logserver )

if [ -z "$1" ]; then
    echo Usage: $0 LOGFILE [PORT]
    exit -1
fi
if [ -n "$2" ]; then
    PORT=$2
else
    PORT=9977
fi

TAIL_CMD="tail -f $1"

function kill_tail {
    # find and kill the tail process that is detached from the current process
    TAIL_PID=$(/bin/ps -eo pid,args | grep "$TAIL_CMD" | grep -v grep | awk '{ print $1 }')
    kill $TAIL_PID
}
trap "kill_tail; exit 0" SIGINT SIGTERM

while true; do
    ( $TAIL_CMD & ) | nc -l -p $PORT -vvv
    kill_tail
done

وncat تنتهي تلقائيا tail -f على الخروج (على نظام التشغيل Mac OS X 10.6.7)!

# simple log server in Bash using ncat
# cf. http://nmap.org/ncat/
touch file.log
ncat -l 9977 -c "tail -f file.log" </dev/null   # terminal window 1
ncat localhost 9977 </dev/null                  # terminal window 2
echo hello > file.log                           # terminal window 3

وطريقة واحدة سيكون للقيام مجرد -ef ملاحظة والبقرى لالذيل مع ppid السيناريو الخاص بك

هل حاولت:

nc -l -p 9977 -c "tail -f $1"

و(غير مجربة)

وأو -e مع scriptfile إذا لم يكن لديك nc -c. قد يكون لديك لnc التي تم جمعها مع خيار GAPING_SECURITY_HOLE. نعم، يجب أن نستنتج المحاذير المناسبة من أن اسم الخيار.

ويمكنك تخزين معرف المنتج من الأمر tail في متغير باستخدام إعادة توجيه باش I / O فقط (انظر <لأ href = "https://stackoverflow.com/questions/3345460/how-to-get-the-pid -of واحد في عملية في واحد في خط أنابيب "> كيفية الحصول على PID لعملية في خط أنابيب ).

# terminal window 1
# using nc on Mac OS X (FreeBSD nc)
: > /tmp/foo
PID=$( { { tail -f /tmp/foo 0<&4 & echo $! >&3 ; } 4<&0 | { nc -l 9977 ;} & } 3>&1 | head -1 )
kill $PID

# terminal window 2
nc localhost 9977

# terminal window 3
echo line > /tmp/foo

وليس إجابة مثالية، ولكنني وجدت حلا لالخفي مسجل عملت على:

#!/bin/sh
tail -f /etc/service/rt4/log/main/current --pid=$$ | grep error

ومن المعلومات $ الذيل:

--pid=PID
          with -f, terminate after process ID, PID dies

والخيار --pid الى الذيل هو أفضل صديق لديك هنا. وسوف تسمح لك مجموع السيطرة على خط أنابيب تعمل في الخلفية. قراءة خيارات الأمر الذيل لمزيد من المرونة في حالة استدارة الملف بنشاط من قبل عملية أخرى التي قد أترك لكم المخلفات وinode غير نشط. في المثال التالي، على الرغم من عدم استخدامها لمعالجة البيانات تدل على "فرض" قيود على الذيل والقدرة ليقولوا ذلك للخروج في أي وقت. ويستخدم هذا لقياس الضغط الخدمة على هتبد.

  # Set the tail to die in 100 second even if we die unexpectedlly.
sleep 100 & ;  ctlpid=$!
tail -q -n 0 --follow=name --retry --max-unchanged-stats=1 --pid=$ctlpid -f  /var/log/httpd/access_log 2>/dev/null | wc –l > /tmp/thisSampleRate &
…. Do some other work
….  Can kill the pipe at any time by killing $ctlpid 
…. Calculate preassure if /tmp/thisSampleRate is ready

هل يمكن استخدام الأمر coproc مرتين.

والمثال الذي يترجم إلى:

coproc TAIL { tail -f $1; }; exec {TAIL[1]}<&-
coproc NC { nc -v -l -p 9977; } <&"${TAIL[0]}" >&1
wait $NC_PID; echo "nc exit code: $!"
kill $TAIL_PID; echo "done"

و(لقد ألقيت -v وecho الزوجين هناك لاستكشاف الأخطاء وإصلاحها.)

وعن طريق coproc يشعر الكثير مثل استخدام Popen () في مختلف لغات البرمجة الأخرى.

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