আপনি যে পাইপটি দিচ্ছেন তা আপনি কীভাবে নির্ধারণ করবেন?


9

ধরা যাক আমার কাছে একটি বাশ স্ক্রিপ্ট আছে log.sh। এই স্ক্রিপ্টে, আমি পাইপ থেকে ইনপুট পড়তে চাই, তবে আমার মধ্যে ইনপুটটি পাইপ করার জন্য ব্যবহৃত আদেশটিও জানতে চাই। উদাহরণ:

tail -f /var/log/httpd/error | log.sh

শেল স্ক্রিপ্টে, আমি কমান্ডটি জানতে চাই tail -f /var/log/httpd/error


আপনি কেন এটি চান তা সম্পর্কে আমি অত্যন্ত কৌতূহলী।
ইগনাসিও ওয়াজকেজ-আব্রামস

আমার ধারণা আপনি কিছু প্রকার জিইউআই প্রোগ্রাম তৈরি করছেন যা পিডগুলি ক্যাপচার এবং প্রসেস করে?
পালবাকুলিচ

আমি জানতে চাই যাতে ফলাফলগুলি কোথায় রাখা যায় তা আমি পার্থক্য করতে পারি। কমান্ড এবং ফাইলের উপর নির্ভর করে আমি বিভিন্ন ক্রিয়া সম্পাদন করতে চাই।
সেন্ট জন জনসন

4
এটি আমার কাছে ন্যূনতম আশ্চর্যের নীতিমালার একটি বড় লঙ্ঘন বলে মনে হচ্ছে। যদি স্ক্রিপ্টটিতে বিভিন্ন পরিস্থিতিতে বিভিন্ন জিনিস করা উচিত হয়, তবে এটি কোনও ইনপুটটি কোথা থেকে আসছে তার পরিবর্তে কমান্ড-লাইন বিকল্প দ্বারা নিয়ন্ত্রণ করা উচিত।
ডেভ শেরোহমান

@ ডেভ, আমি সম্মত আসুন আমরা কেবল এই উদাহরণটির জন্য বলি, আসন্ন আদেশটি কী তা আমি 'জানতে চাই'।
সেন্ট জন জনসন

উত্তর:


7

আকিরা ব্যবহারের পরামর্শ দিলেন lsof

আপনি এটি কীভাবে স্ক্রিপ্ট করতে পারেন তা এখানে:

whatpipe2.sh

#!/bin/bash

pid=$$
pgid=$(ps -o pgid= -p $pid)
lsofout=$(lsof -g $pgid)
pipenode=$(echo "$lsofout" | awk '$5 == "0r" { print $9 }')
otherpids=$(echo "$lsofout" | awk '$5 == "1w" { print $2 }')
for pid in $otherpids; do
    if cmd=$(ps -o cmd= -p $pid 2>/dev/null); then
        echo "$cmd"
        break
    fi
done

এটি চালানো:

$ tail -f /var/log/messages | ./whatpipe2.sh
tail -f /var/log/messages
^C

আর একটি উপায় প্রক্রিয়া গ্রুপ ব্যবহার করা হয়।

whatpipe1.sh

#!/bin/bash    

pid=$$
# ps output is nasty, can (and usually does) start with spaces
# to handle this, I don't quote the "if test $_pgrp = $pgrp" line below
pgrp=$(ps -o pgrp= -p $pid)
psout=$(ps -o pgrp= -o pid= -o cmd=)
echo "$psout" | while read _pgrp _pid _cmd; do
    if test $_pgrp = $pgrp; then
        if test $_pid != $pid; then
            case $_cmd in
            ps*)
                # don't print the "ps" we ran to get this info
                # XXX but this actually means we exclude any "ps" command :-(
                ;;
            *)
                echo "$_cmd"
                ;;
            esac
        fi
    fi
done

এটি চালানো:

$ tail -f /var/log/messages | ./whatpipe1.sh
tail -f /var/log/messages
^C

নোটটি কেবলমাত্র পাইপটির বাম দিকের কমান্ডটি দেখার জন্য যথেষ্টক্ষণ চালিত হলে কেবলমাত্র তারা উভয়ই কাজ psকরে দেখুন। আপনি বলেছিলেন যে আপনি এটি ব্যবহার করছেন tail -f, সুতরাং আমি সন্দেহ করি এটি একটি সমস্যা।

$ sleep 0 | ./whatpipe1.sh 

$ sleep 1 | ./whatpipe1.sh
sleep 1

এই বিশাল পোস্টের পরিবর্তে আমি lsof- ভিত্তিক স্ক্রিপ্টের সাথে ২ য় উত্তর দিতাম। যে এক জন্য দুর্দান্ত কাজ।
আকির

ধন্যবাদ এটি পরিষ্কার এবং পোর্টেবল করার জন্য কয়েকটি প্রচেষ্টা নিয়েছিল। প্রোফস এবং lsof সম্পর্কে কয়েকটি জিনিস শিখেছে। ধারণার জন্য ধন্যবাদ।
মাইকেল

আমি আপনার গ্রহণ করেছি কারণ এটি একটি উত্তর দেয় যা অন্য লোকেরা সরাসরি ব্যবহার করতে পারে। @ আকীরা, আপনি বেশিরভাগ কাজটি করেছেন, দুঃখিত আমি আপনাকেও গ্রহণ করতে পারি নি।
সেন্ট জন জনসন

10

পাইপটি আপনার প্রক্রিয়াটির উন্মুক্ত ফাইলডেস্ক্রিপ্টরের তালিকায় একটি প্রবেশ হিসাবে উপস্থিত হবে:

 % ls -l /proc/PID/fd
 lr-x------ 1 xyz xyz 64 Feb 11 08:05 0 -> pipe:[124149866]
 lrwx------ 1 xyz xyz 64 Feb 11 08:05 1 -> /dev/pts/2
 lrwx------ 1 xyz xyz 64 Feb 11 08:05 2 -> /dev/pts/2
 lr-x------ 1 xyz xyz 64 Feb 11 08:05 10 -> /tmp/foo.sh

আপনি এর মতো কিছু ব্যবহার করতে পারেন:

 % lsof -p PID
 sh      29890 xyz  cwd    DIR   0,44    4096  77712070 /tmp
 sh      29890 xyz  rtd    DIR   0,44    4096  74368803 /
 sh      29890 xyz  txt    REG   0,44   83888  77597729 /bin/dash
 sh      29890 xyz  mem    REG   0,44 1405508  79888619 /lib/tls/i686/cmov/libc-2.11.1.so
 sh      29890 xyz  mem    REG   0,44  113964  79874782 /lib/ld-2.11.1.so
 sh      29890 xyz    0r  FIFO    0,6         124149866 pipe
 sh      29890 xyz    1u   CHR  136,2                 4 /dev/pts/2
 sh      29890 xyz    2u   CHR  136,2                 4 /dev/pts/2
 sh      29890 xyz   10r   REG   0,44      66  77712115 /tmp/foo.sh

সুতরাং, পাইপের ইনোডের চেয়ে :) আপনি এখন /proc/এই পাইপের নীচে প্রতিটি অন্যান্য প্রক্রিয়া অনুসন্ধান করতে পারেন । তাহলে আপনার কাছে যে কমান্ডটি পাইপ দিচ্ছে তা আপনার কাছে থাকবে:

 % lsof | grep 124149866 
 cat     29889 xyz    1w  FIFO                0,6          124149866 pipe
 sh      29890 xyz    0r  FIFO                0,6          124149866 pipe

এই উদাহরণে, catওয়ার্ডগুলিতে পাইপ করা হয়েছে sh। মধ্যে /proc/29889আপনি একটি ফাইল নামক জানতে পারেন cmdlineযা আপনাকে বলে, কি ঠিক বলা হয়েছিল:

 % cat /proc/29889/cmdline
 cat/dev/zero%  

কমান্ড লাইনের ক্ষেত্রগুলি NUL দ্বারা পৃথক করা হয়েছে, এটি কিছুটা কুৎসিত দেখায় :)


কোন উত্তর গ্রহণ করতে হবে তা আমি জানি না। @ আকীরা, আপনি কীভাবে এটি নির্ধারণ করবেন সে সম্পর্কে আপনি প্রকৃত ভাঙ্গন দিয়েছেন, যখন @ মাইকেল আমাকে একটি স্ক্রিপ্ট দিয়েছেন। জিনিসগুলিকে দুর্দান্ত করে তোলার উপায় difficult
সেন্ট জন জনসন

1

lsofআধুনিক লিনাক্স বিতরণে আধুনিক ব্যবহার করে এখানে একটি কমপ্যাক্ট সমাধান রয়েছে :

cmd=$(lsof -t -p $$ -a -d 0 +E | while read p; do
    [ $p -ne $$ ] && echo "$(tr \\000 " " </proc/$p/cmdline)"
done)

এটি +Eবর্তমান শেল প্রক্রিয়াতে ( ) এর এফডি 0 এর শেষ পয়েন্ট ফাইলগুলি ( ) তালিকাভুক্ত করে -p $$ -a -d 0, তবে কেবলমাত্র পাইপগুলিতে আউটপুট সীমাবদ্ধ করে ( -t), পাইপের উভয় দিকে পিআইডি সরবরাহ করে।

মনে রাখবেন যে:

  1. উত্স প্রান্তে একাধিক পিআইডি পাওয়া যেতে পারে, উদাহরণস্বরূপ { echo Hi; sleep 5 ; } | whatpipe.shসম্ভবত একটি bash(ইনপুট সাবশেল) এবং পাওয়া যাবে sleep 5
  2. +Elsofসংকলিত থাকলে কেবল উপলভ্য -DHASUXSOCKEPT। এটি বেশিরভাগ আধুনিক লিনাক্সের ডিস্ট্রোসের ক্ষেত্রে সত্য হওয়া উচিত, তবে যেকোন উপায়ে আপনার ইনস্টলেশন পরীক্ষা করুন:lsof -v 2>&1 | grep HASUXSOCKEPT
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.