কমান্ডগুলির ব্যাকগ্রাউন্ড পাইপযুক্ত অনুক্রমের যে কোনও কমান্ডের পিআইডি পান


11

যদি, মধ্যে bash, আমি কার্যকর:

cmd1 | cmd2 | ... | cmdi | ... | cmdn &

যেখানে cmd{1..n}পৃথক নাও হতে পারে, আমি কীভাবে এর পিআইডি পাব cmdi? বিকল্পভাবে, আমি কীভাবে cmdiপ্রক্রিয়াটি সংকেত করতে পারি ? (উদাহরণস্বরূপ, এটি প্রেরণ করবেন SIGUSR1?) pkill/ pgrep, pidofইত্যাদি ভাল উত্তরের মতো বলে মনে হচ্ছে না, কারণ cmdiএকই পাইপলাইনের অংশ হিসাবে সম্ভবত চলার অন্যান্য উদাহরণগুলি । আমার জন্য jobs -pপিআইডি দেয়cmd1

iকিছু হতে পারে {1..n}



1
@ জি-ম্যান কেয়ার ব্যাখ্যা করতে? আমি কেবলমাত্র পৃষ্ঠের মিল খুঁজে পাই এবং রমেশের উত্তরে আমি যেমন ব্যাখ্যা করেছি, কমান্ডের সংশোধন করা খুব বেশি কার্যকর নয়।
মুরু

সুফেরিয়াল মিল? cat /var/run/out | nc -l 8080শুধু কৃত্রিম অনুরূপ করতে cmd1 | cmd2? আপনার সীমাবদ্ধতা, আপনি যে খালি হাড়ের পাইপলাইন টাইপ করতে চান এবং তারপরে পিআইডিগুলি পুনরুদ্ধার করতে চান তা (1) প্রশ্নের মধ্যে বর্ণিত নয় এবং (2) ভাল, সাধারণ সমাধানের অনুমতি দেওয়া সম্ভব নয় unlikely
জি-ম্যান বলছেন 'পুনরায় ইনস্টল করুন মনিকা'

@ জি-ম্যান বিপরীতে, আপনি সীমাবদ্ধতা চাপিয়ে দিচ্ছেন যে সরলভাবে বলা হয়নি। cmd1 | cmd2উভয় পিআইডি সহজেই গ্রহণযোগ্য এমন একটি অত্যন্ত বিশেষ কেস। আমি এন সম্পর্কে কিছু বলেছি? তাহলে আপনি কেন এন = 2 ধরে নিবেন? আমি কি সেমিডিডি কিছু বললাম? তাহলে আপনি কেন ধরে নেবেন যে আমি সেমিডিডি সংশোধন করতে পারব? আমি একটি সাধারণ সমাধান চাইছি এবং আপনি বিধিনিষেধ আরোপ করছেন।
মুরু

উত্তর:


6

প্রশ্নের মূল সংস্করণের জন্য, যখন কেবলমাত্র শেষ কমান্ডের পিআইডি পছন্দ হয়েছিল, বিশেষ ভেরিয়েবলটি $!নিখুঁত।

foo | bar | baz &
baz_pid=$!

অন্যান্য প্রক্রিয়াগুলির পিআইডি তে তেমন কোনও সহজ অ্যাক্সেস নেই।

আসল বোর্ন শেল থেকে প্রায় শেষ যেটি ছিল তার শেষের দিকে, পাইপলাইনে $pipestatus(এক্সপি) এবং $PIPESTATUS(বাশ) যোগ করার জন্য দীর্ঘ সময় লেগেছে , শেষ পর্যন্ত আমাদেরকে একটি পাইপলাইনে সমস্ত প্রস্থান স্থিতির অ্যাক্সেস দিয়েছিল $?। হতে পারে $!শেষ অবধি কিছুটা অ্যানালাসাস ঘটবে ।


আমি যদি তালিকায় একটি স্বেচ্ছাসেবক কমান্ডের পিআইডি জিজ্ঞাসা করার জন্য প্রশ্নটি সম্পাদনা করি তবে আপনি কি আপত্তি করবেন? নাকি আমার নতুন প্রশ্ন শুরু করা উচিত?
মুরু

সেই উত্তরের জন্য আপনাকে সম্ভবত আরও দীর্ঘ অপেক্ষা করতে হবে। স্ট্যাকএক্সচেঞ্জ সাইট সংগঠন সম্পর্কে আমার

ঠিক আছে, তাত্ক্ষণিক সমস্যার সমাধান হয়েছে, এখন কৌতূহল দায়িত্বে রয়েছে। আমি তখন এটি সম্পাদনা করব। আমি কেবল মাথা উঁচু করে দেখেছি যেহেতু আমি প্রশ্নগুলি মারাত্মকভাবে পরিবর্তিত হতে দেখেছি এবং পুরানো উত্তরগুলি খুব বাইরে খুঁজে দেখছি।
মুড়ু

@ মুরু - নোট করুন এটির জন্য এটি একটি নতুন প্রশ্ন করা আরও ভাল হত।
slm

@ এসএমএল যথাযথভাবে উল্লেখ করা হয়েছে। ভবিষ্যতেও তা করবে।
মুড়ু

4

আমি মনে করি আপনি এখানে পরামর্শ মত কিছু করতে পারেন ।

(ls -l | echo "Hello" | df -h & echo $! >&3 ) 3>pid

এখানে উপরের উদাহরণে, আমি তৃতীয় পাইপযুক্ত প্রক্রিয়াটির পিডটি পুনরুদ্ধার করেছি এবং এটি ফাইল পিডে লিখে রেখেছি। আমি যে কোনও পাইপ প্রক্রিয়াটির জন্য এটি নোট করতে পারি।


আকর্ষণীয়, তবে এর মধ্যে কমান্ডের সেটটি সংশোধন করা জড়িত। কমান্ডগুলি কার্যকর করার পরে খুব বেশি ব্যবহার হয় না।
মুড়ু

@ মুরু - কি? কোনও পিআইডি কার্যকর হওয়ার পরে কোন ব্যবহার হয়? আপনি কি পাইপলাইনের পিআইডি চান? jobs -p। এটি দিয়ে সংকেত SIGPIPE। আপনি কি চান cmdi- এটি।
মাইকজার্ভ

1
@ মিকসার্ভ যদি না হয় তারা পটভূমিতে থাকে, আমাদের কথা মতো চলতে থাকে running কোন জাদু দ্বারা আমি তার জন্য কমান্ড লাইনটি পরিবর্তন করার কথা?
মুরু

1
@ মুরু এটি একটি জাদু হবে। আপনার একটি ডিবাগার দরকার।
মাইকজার্ভ

ব্যাকগ্রাউন্ড প্রক্রিয়াগুলি শুরু করার জন্য, তাদের কোনও স্থানে পৌঁছানোর অপেক্ষায় এবং তারপরে তাদের হত্যা করার জন্য এটি একটি দরকারী নিদর্শন বলে আমি মনে করি। যদি কেউ আগ্রহী হন তবে: gist.github.com/MatrixManAtYrService/…
ম্যাট্রিক্সম্যানএটিওয়াইর সার্ভিসিস

2

একটি খুব-বহনযোগ্য নয়, লিনাক্স-নির্দিষ্ট সমাধান হতে পারে যেগুলি পাইপগুলি সংযুক্ত করে সেগুলি ব্যবহার করে প্রক্রিয়াগুলি ট্র্যাক করে। আমরা পাইপলাইনে প্রথম ( jobs -p) এবং শেষ ( $!) কমান্ডের পিআইডি পেতে পারি । উভয়ই পিআইডি ব্যবহার করে, এই স্ক্রিপ্টটি কাজটি করতে পারে:

#! /bin/bash

PROC=$1
echo $PROC

if [[ $(readlink /proc/$PROC/fd/1) =~ ^pipe: ]]
then
    # Assuming first process in chain...
    NEXT_FD=1
elif [[ $(readlink /proc/$PROC/fd/0) =~ ^pipe: ]]
then
    # Last process in chain...
    NEXT_FD=0
else
    # Doesn't look like a pipe.
    exit
fi

NEXT_PROC_PIPE=$(readlink /proc/$PROC/fd/$NEXT_FD)

while [[ $NEXT_PROC_PIPE =~ ^pipe: ]] 
do
    PROC=$(find /proc/*/fd -type l -printf "%p/%l\n" 2>/dev/null | awk -F'/' '($6 == "'"$NEXT_PROC_PIPE"'") && ($3 != "'$PROC'" ) {print $3}')
    NEXT_PROC_PIPE=$(readlink /proc/$PROC/fd/$NEXT_FD)
    echo $PROC
done


0

আমি এই কোডটিতে এখানে শূন্য-ভিত্তিক অ্যারে ব্যবহার করি। আপনি যা চালাচ্ছেন তা যত্নবান হন eval

#!/bin/bash

cmd=('sleep 10' 'sleep 2' 'sleep 5')
first=1
for c in "${cmd[@]}"; do
  ((first)) && { pipe=$c; first=0; } || pipe+='|'$c
done
shopt -u lastpipe
eval $pipe &

printf 'Pipe:\n%s\n\n' "$pipe"

shellpid=$BASHPID
parent=$(ps -o pid= --ppid $shellpid | head -n -1)
declare -a pids=()
mapfile -t pids < <(printf '%s\n' $(ps -o pid= --ppid $parent))
printf '%s\n' 'Listing the arrays:'
printf '%2s %6s %s\n' i PID command
for i in "${!cmd[@]}"; do
    printf '%2d %6d %s\n' "$i" "${pids[i]}" "${cmd[i]}"
done

printf '\n%s\n' 'ps listing:'
ps xao pid,ppid,command | head -n 1
ps xao pid,ppid,command | tail | head -n -3
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.