সিউডো-টার্মিনাল ডিভাইসের অন্য প্রান্তে কারা আছেন তা আমরা কীভাবে জানতে পারি?


26

যদি আমি এটি করি:

echo foo > /dev/pts/12

কিছু প্রক্রিয়া foo\nএটির ফাইল বর্ণনাকারী থেকে শুরু করে মাস্টার সাইডে পড়বে ।

সেই (প্রক্রিয়াগুলি) প্রক্রিয়াটি (এস) কী কী তা খুঁজে পাওয়ার কোনও উপায় আছে?

বা অন্য কথায়, আমি কীভাবে এক্সটার্ম / এসএসডি / স্ক্রিপ্ট / স্ক্রিন / টিএমক্স / আশা / সোকাট ... এর অন্য প্রান্তে খুঁজে পাব /dev/pts/12?

lsof /dev/ptmxযে প্রক্রিয়াগুলিতে যে কোনও প্রাইটির মাস্টার দিকে ফাইল বর্ণনাকারী রয়েছে তা আমাকে বলবে। কোনও প্রক্রিয়া নিজেই ptsname()( TIOCGPTNআইওসিটিএল) মাস্টার পাশের নিজস্ব এফডি এর উপর ভিত্তি করে স্লেভ ডিভাইসটি খুঁজে পেতে ব্যবহার করতে পারে, তাই আমি এটি ব্যবহার করতে পারি:

gdb --batch --pid "$the_pid" -ex "print ptsname($the_fd)"

পিড / এফডি প্রত্যেকে lsofএই ম্যাপিংটি তৈরি করতে ফিরে এসেছিল , তবে সেই তথ্য পাওয়ার জন্য আরও প্রত্যক্ষ, নির্ভরযোগ্য এবং কম অনুপ্রবেশমূলক উপায় আছে কি?


এই কমান্ডের সাহায্যে আপনি চান কি? sudo find /proc/*/fd/0 -ls | grep '/dev/pts/4', /proc/PIDআউটপুট হিসাবে পিআইডি ( ) এর তালিকা সরবরাহ করবে ।
slm

@ এসএলএম, না, অন্য কথায়, আমি অনুসন্ধান করতে চাই যে কোন এক্সটার্ম / এসএসডি / স্ক্রিপ্ট / স্ক্রিন / টিএমউক্স / আশা / সোকাট ... এর অন্য প্রান্তে রয়েছে /dev/pts/4। সাধারণত, এটি সেই প্রক্রিয়াগুলির একটি সাধারণ পূর্বপুরুষ হবে যা /dev/pts/4খোলা আছে, তবে অগত্যা নয়।
স্টাফেন চেজেলাস

1
এটি সকেটগুলির সাথে আরও খারাপ - আপনার কার্নেল ডিবাগার দরকার!
গিলস 'তাই খারাপ হওয়া বন্ধ করুন'

1
@ ফ্যালাসনামস - আমি প্রশ্নটি বোঝার অর্থটি বুঝতে পেরেছিলাম - সম্ভবত ভুলভাবে - কোন প্রক্রিয়াটি ডেটা পাঠ করা হয় তা নয় - যেমন টার্মিনালে প্রথম শেলটি আহ্বান করা হয়েছিল - তবে কী প্রক্রিয়া আসলে এটিকে মাস্টার দিক থেকে পাঠ করে। উদাহরণস্বরূপ, আমি যদি একটি শেল চালু করি তবে screenএটি হ'ল screenডিভাইসটির জীবনযাপনের জন্য pty দাসকে সক্রিয়ভাবে বরাদ্দ করে এবং পরিচালনা করে তবে - যেমন, আমি মনে করি - শেলটি সেই টিটিটির জন্য প্রক্রিয়া-নেতা হিসাবে তৈরি করা হয়েছে এবং আপনার হিসাবে আউটপুট শো, আপনি পাবেন bashবা যা psকিছুই না screen। আমি পিডের উপর ভিত্তি করে কয়েক xtermsপিছনে ট্রেস করেছিলাম তবে এটি আলগা ছিল। xterm/proc/locks
মাইকসার্ভ

1
সম্পর্কিত: unix.stackexchange.com/questions/492302
মশাই

উত্তর:


3

প্রথমে আমি xtermযে xtermতথ্য পেয়েছি তার ভিত্তিতে পিডের দিকে কয়েক সেকেন্ড পিছনে ট্রেস করার চেষ্টা করেছি /proc/locksতবে এটি আলগা ছিল। আমার অর্থ, এটি কাজ করেছিল, আমি মনে করি, তবে এটি সর্বোত্তম পরিস্থিতিতে ছিল - ফাইলটি যে সমস্ত তথ্য সরবরাহ করে এবং এটি কেবল তার সামগ্রীতে এবং টার্মিনাল প্রক্রিয়াগুলির মধ্যে মিল বলে মনে হয় তার সাথে মিলে যায় এমন সমস্ত তথ্য আমি পুরোপুরি বুঝতে পারি না।

তারপরে আমি ptys এর মধ্যে lsof/straceএকটি সক্রিয় write/talkপ্রক্রিয়া দেখার চেষ্টা করেছি। আমি বাস্তবে এর আগে কোনও প্রোগ্রামই আগে কখনও ব্যবহার করি নি, তবে তারা নির্ভর করে বলে মনে হচ্ছে utmp। যদি আমার টার্গেট পাইটির utmpকোনও কারণেই যদি কোনও প্রবেশপথ না থাকে তবে তারা উভয়ই এটি বিদ্যমান বলে স্বীকার করতে অস্বীকার করেছিল। এর আশেপাশে কোনও উপায় থাকতে পারে তবে আমি এটিকে পরিত্যাগ করার জন্য যথেষ্ট বিভ্রান্ত ছিলাম।

আমি udevadm136 এবং 128 মেজর নাম্বার ডিভাইস নোডগুলির সাথে ptsএবং ptmযথাক্রমে বিজ্ঞাপনিত হিসাবে কিছু আবিষ্কারের চেষ্টা করেছি /proc/tty/drivers, তবে আমারও সেই সরঞ্জামটির সাথে খুব কার্যকর অভিজ্ঞতা নেই এবং আবারও যথেষ্ট কিছুই প্রমাণিত হয়নি। আকর্ষণীয়ভাবে, যদিও, আমি লক্ষ্য করেছি যে :minউভয় ডিভাইসের ধরণের পরিসীমাটি স্তম্ভিত করে তালিকাভুক্ত করা হয়েছিল 0-1048575

যদিও আমি এই কার্নেল ডকটি পুনর্বিবেচনা না করেছিলাম যা আমি এর ক্ষেত্রে সমস্যাটি নিয়ে ভাবতে শুরু করি mount। আমি এর আগে বেশ কয়েকবার পড়েছি কিন্তু যখন সেই লাইনে অবিরত গবেষণা আমাকে এই 2012 /dev/ptsপ্যাচসেটের দিকে নিয়েছিল আমার ধারণা ছিল:

sudo fuser -v /dev/ptmx

আমি ভাবলাম আমি সাধারণত একটি এর সাথে প্রক্রিয়াগুলি সংযুক্ত করতে কী ব্যবহার করব mount? এবং যথেষ্ট নিশ্চিত:

                     USER        PID ACCESS COMMAND
/dev/ptmx:           root      410   F.... kmscon
                     mikeserv  710   F.... terminology

সুতরাং সেই তথ্য দিয়ে আমি করতে পারি, উদাহরণস্বরূপ terminology:

sudo sh -c '${cmd:=grep rchar /proc/410/io} && printf 1 >/dev/pts/0 && $cmd'
###OUTPUT###
rchar: 667991010
rchar: 667991011

আপনি দেখতে পাচ্ছেন, সামান্য সুস্পষ্ট পরীক্ষার মাধ্যমে এই জাতীয় প্রক্রিয়াটি বেশ নির্ভরযোগ্যভাবে একটি স্বেচ্ছাসেবীর প্রতিফলনের মাস্টার প্রক্রিয়াটিকে আউটপুট করা যায়। সকেটগুলির বিষয়ে, আমি মোটামুটি নির্দিষ্টভাবে একজন socatডিবাগারের বিপরীতে ব্যবহার করে সেদিকেই যেতে পারি, তবে কীভাবে তা আমি সোজা করতে পারি না। তবুও, আমার সন্দেহ হয় ssআপনি যদি আমার চেয়ে বেশি পরিচিত হন তবে এটি সহায়তা করতে পারে:

sudo sh -c 'ss -oep | grep "$(printf "pid=%s\n" $(fuser /dev/ptmx))"'

সুতরাং আমি এটি আরও কিছুটা স্পষ্ট পরীক্ষার সাথে সেট আপ করেছি, আসলে:

sudo sh <<\CMD
    chkio() {
        read io io <$1
        dd bs=1 count=$$ </dev/zero >$2 2>/dev/null
        return $((($(read io io <$1; echo $io)-io)!=$$))
    }
    for pts in /dev/pts/[0-9]* ; do
        for ptm in $(fuser /dev/ptmx 2>/dev/null)
            do chkio /proc/$ptm/io $pts && break
        done && set -- "$@" "$ptm owns $pts"
    done
    printf %s\\n "$@"
 CMD

এটি প্রতিটি পিটিআইয়ের কাছে নাল $$নাইট \0বাইটগুলি প্রিন্ট করে এবং প্রতিটি মাস্টার প্রক্রিয়াটির আইওটিকে আগের চেকের বিপরীতে পরীক্ষা করে। পার্থক্য যদি হয় $$তবে এটি পিটিটি pty এর সাথে যুক্ত করে। এটি বেশিরভাগ ক্ষেত্রেই কাজ করে। আমার অর্থ, এটি আমার কাছে ফিরে আসে:

410 owns /dev/pts/0
410 owns /dev/pts/1
710 owns /dev/pts/2

কোনটি সঠিক, তবে স্পষ্টতই, এটি সামান্য সাম্প্রদায়িকতা। আমি বলতে চাইছি, সেই সময়ে যদি অন্য একজনের মধ্যে একগুচ্ছ ডেটা পড়ছিল তবে সম্ভবত এটি মিস হবে। আমি sttyপ্রথমে স্টপ বিট বা এরকম কিছু পাঠানোর জন্য কীভাবে অন্য একটি পিটিআইয়ের মোডগুলি পরিবর্তন করতে হবে তা বোঝার চেষ্টা করছি যাতে আমি এটি ঠিক করতে পারি।


2

আপনি শুধু যারা সংযোগ মালিক খুঁজছেন এবং যেখানে তারা থেকে সংযুক্ত হয় যারা কমান্ড ভাল কাজ করবে।

$ who
falsenames   tty8         Jun 13 16:54 (:0)
falsenames   pts/0        Jun 16 11:18 (:0)
falsenames   pts/1        Jun 16 12:59 (:0)
falsenames   pts/2        Jun 16 13:46 (:0)
falsenames   pts/3        Jun 16 14:10 (:0)
falsenames   pts/4        Jun 16 16:41 (:0)

আপনি যদি সেই সংযোগে কী শুনছেন তা জানতে চান, তবে ডাব্লুটি এটি শেষে দেখায়।

$ w
 16:44:09 up 2 days, 23:51,  6 users,  load average: 0.26, 0.98, 1.25
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
falsenames   tty8     :0               Fri16    2days 53:36   0.59s x-session-manager
falsenames   pts/0    :0               11:18    5:25m  1:10   1:10  synergys -a 10.23.8.245 -c .synergy.conf -f -d DEBUG
falsenames   pts/1    :0               12:59    3:44m  0.05s  0.05s bash
falsenames   pts/2    :0               13:46    2:52m  0.11s  0.11s bash
falsenames   pts/3    :0               14:10    2:17   0.07s  0.07s bash
falsenames   pts/4    :0               16:41    1.00s  0.04s  0.00s w

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

$ ps -t pts/0 --forest 
  PID TTY          TIME CMD
23808 pts/0    00:00:00 bash
23902 pts/0    00:03:27  \_ synergys

দ্রষ্টব্য, এটি সময় অনুসারে রেড হেরিংগুলিতে ডেকে আনতে পারে। তবে এটি শুরু করার জন্য ভাল জায়গা।

$ tty
/dev/pts/4
$ ps -t pts/4 --forest
  PID TTY          TIME CMD
27479 pts/4    00:00:00 bash
 3232 pts/4    00:00:00  \_ ps
27634 pts/4    00:00:00 dbus-launch

ধন্যবাদ, তবে আমি যা খুঁজছি তা নয়। উদাহরণস্বরূপ, আমি টার্মিনাল অ্যাপ্লিকেশনটির পিড (Xterm / gnome- টার্মিনাল ...) সন্ধান করতে চাই /dev/pts/4যেখানে আপনি সেই wআদেশটি চালিয়েছিলেন ।
স্টাফেন চেজেলাস

দুঃখিত, আমি প্রথমবার স্ক্যান করার সময় পিড অংশটি পুরোপুরি মিস করেছি। আমি ভেবেছিলাম আপনি শেষ প্রক্রিয়াটির নামটি জানতে চান।
ফ্যালসনামস

2

আমার কিউমুতে একই সমস্যা ছিল এবং শেষ পর্যন্ত আমি খুব খারাপ সমাধান পেয়েছি (তবে এখনও একটি সমাধান): প্রক্রিয়াটির স্মৃতিশক্তি পার্স করে।

এটি এখানে কাজ করছে কারণ আমি জানি যে Qemu একটি নির্দিষ্ট ফর্ম্যাট সহ একটি স্ট্রিংয়ে রিমোট pts সংরক্ষণ করছে এবং গাদাতে বরাদ্দ। হতে পারে এটি অন্যান্য পরিস্থিতিতেও কয়েকটি পরিবর্তন সহ এবং ফুজার আউটপুট থেকে পিডটিকে পুনরায় ব্যবহার করে (অন্য উত্তরটি পরীক্ষা করে দেখুন) কাজ করতে পারে।

কোডটি এখান থেকে অভিযোজিত ।

#! /usr/bin/env python

import sys
pid = sys.argv[1]

import re
maps_file = open("/proc/" + pid + "/maps", 'r')
mem_file = open("/proc/" + pid + "/mem", 'r', 0)
for line in maps_file.readlines():
    # You may want to remove the 'heap' part to search all RAM
    m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r]).*\[heap\]', line)
    if m and m.group(3) == 'r':
        start = int(m.group(1), 16)
        end = int(m.group(2), 16)
        mem_file.seek(start)
        chunk = mem_file.read(end - start)
        # You may want to adapt this one to reduce false matches
        idx = chunk.find("/dev/pts/")
        if idx != -1:
            end = chunk.find("\0", idx)
            print chunk[idx:end]
maps_file.close()
mem_file.close()
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.