কমান্ড লাইন ব্যবহার করে কোনও প্রক্রিয়া শুরু করার পরে STDERR / STDOUT পুনর্নির্দেশ করবেন?


127

শেলের মধ্যে আপনি পুনর্নির্দেশ > <ইত্যাদি করতে পারেন , তবে কোনও প্রোগ্রাম শুরু হওয়ার পরে কীভাবে?

আমি এখানে এই প্রশ্নটি জিজ্ঞাসা করতে এসেছি, আমার টার্মিনালের পটভূমিতে চলমান একটি প্রোগ্রাম বিরক্তিকর পাঠ্যকে আউটপুট দেয়। এটি একটি গুরুত্বপূর্ণ প্রক্রিয়া তাই পাঠ্যটি এড়াতে আমাকে অন্য শেলটি খুলতে হবে। আমি সক্ষম হতে চাই >/dev/nullবা অন্য কোনও পুনর্নির্দেশকে সক্ষম করতে চাই যাতে আমি একই শেলটিতে কাজ চালিয়ে যেতে পারি।


আমি জানি যে STDOUT / STDERR পুনর্নির্দেশের সবচেয়ে সহজ উপায় হ'ল তাদের ফাইল বর্ণনাকারীদের কাঁটাচাঁটি করার আগে ডুপ 2 করা। এটি মোটামুটি মানসম্পন্ন অনুশীলন, এবং সম্ভবত শেলগুলি এখনই এটি সম্পাদন করে। এটির কোনও উত্তর দেয় কিনা তা নিশ্চিত নই, তবে আমি ভাবছি এটির ভাল হওয়ার সম্ভাবনা হ্রাস পাবে।
স্টিফান মাই

উত্তর:


124

আপনার টিটিটি বন্ধ এবং পুনরায় খোলার সংক্ষিপ্ততা (যেমন লগিং অফ এবং পিছনে ফিরে আসা, এটি প্রক্রিয়াতে আপনার কিছু পটভূমি প্রক্রিয়াও শেষ করতে পারে) আপনার কাছে কেবল একটি পছন্দ বাকি রয়েছে:

  • জিডিবি ব্যবহার করে প্রশ্নে প্রক্রিয়াটি সংযুক্ত করুন এবং চালান:
    • পি ডুপ 2 (খোলা ("/ দেব / নাল", 0), 1)
    • পি ডুপ 2 (খোলা ("/ দেব / নাল", 0), 2)
    • আলাদা
    • অব্যাহতিপ্রাপ্ত

উদাহরণ:

$ tail -f /var/log/lastlog &
[1] 5636

$ ls -l /proc/5636/fd
total 0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 0 -> /dev/pts/0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 1 -> /dev/pts/0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 2 -> /dev/pts/0
lr-x------ 1 myuser myuser 64 Feb 27 07:36 3 -> /var/log/lastlog

$ gdb -p 5636
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Attaching to process 5636
Reading symbols from /usr/bin/tail...(no debugging symbols found)...done.
Reading symbols from /lib/librt.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/librt.so.1
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/libpthread.so.0...(no debugging symbols found)...done.
[Thread debugging using libthread_db enabled]
[New Thread 0x7f3c8f5a66e0 (LWP 5636)]
Loaded symbols for /lib/libpthread.so.0
Reading symbols from /lib/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2

(no debugging symbols found)
0x00007f3c8eec7b50 in nanosleep () from /lib/libc.so.6

(gdb) p dup2(open("/dev/null",0),1)
[Switching to Thread 0x7f3c8f5a66e0 (LWP 5636)]
$1 = 1

(gdb) p dup2(open("/dev/null",0),2)
$2 = 2

(gdb) detach
Detaching from program: /usr/bin/tail, process 5636

(gdb) quit

$ ls -l /proc/5636/fd
total 0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 0 -> /dev/pts/0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 1 -> /dev/null
lrwx------ 1 myuser myuser 64 Feb 27 07:36 2 -> /dev/null
lr-x------ 1 myuser myuser 64 Feb 27 07:36 3 -> /var/log/lastlog
lr-x------ 1 myuser myuser 64 Feb 27 07:36 4 -> /dev/null
lr-x------ 1 myuser myuser 64 Feb 27 07:36 5 -> /dev/null

আপনিও বিবেচনা করতে পারেন:

  • ব্যবহার screen; স্ক্রিনটি বেশ কয়েকটি ভার্চুয়াল টিটিওয়াই সরবরাহ করে আপনি নতুন এসএসএইচ / টেলনেট / ইত্যাদি, সেশনগুলি না খোলার মধ্যে স্যুইচ করতে পারেন
  • ব্যবহার nohup; এটি আপনাকে ... প্রক্রিয়াতে কোনও ব্যাকগ্রাউন্ড প্রক্রিয়া না হারিয়ে আপনার সেশনটি বন্ধ এবং পুনরায় খুলতে সহায়তা করে।

1
আপনার জিডিবি উত্তরটি লেজ-এফ ফাইলের সাথে কাজ করে না, এবং এটি জিসিসি-জিজিডিবি সমন্বিত সি-তে একটি পরীক্ষা প্রোগ্রামের সাথে কাজ করে না যা প্রতি সেকেন্ডে একটি প্রিন্টফ করে। কনটেন্ট আরও জিডিবি কমান্ড চালানো অসম্ভব করে তোলে, কমান্ডটি বিচ্ছিন্ন হয়ে যাবে, তারপরে প্রস্থান করুন।
ইয়ান কেলিং

বিচ্ছিন্নতা সম্পর্কে সঠিক, এটি 2 টা। :) জিডিবি সলিউশন নিয়ে ঠিক কী কাজ হয়নি?
ভ্লাদর

12
আপনি যদি stdout / stderr (/ dev / নাল ছাড়াও কিছুতেই স্পষ্টভাবে) পুনঃনির্দেশ করছেন তবে আপনার লেখার অ্যাক্সেস সহ ফাইলটি খুলতে হবে - open("/path/to/new/stdout",O_WRONLY)। O_WRONLY সম্ভবত উপলব্ধ হবে না, যদিও; 1লিনাক্স / গ্লিবসি-তে এর মান ।
জান্ডার

13
সতর্কতার শব্দ: জিডিবিতে কোনও প্রক্রিয়াতে সংযুক্তি প্রক্রিয়াটি বিরত না করা অবধি প্রক্রিয়াটি বিরতি দেয়।
মার্টি বি

1
@ জেন্ডার এর মন্তব্যে যুক্ত করা ছাড়াও 1025অ্যাক্টিভেটস ব্যবহার করে যা আপনি একই স্টাডারে স্টার্ডার এবং স্টাডআউট উভয়কে পুনঃনির্দেশিত করলে কার্যকর হয়। O_APPENDO_WRONLY
spectras

57

এটি করবে:

strace -ewrite -p $PID

এটি এমন পরিষ্কার নয় (এর মতো লাইনগুলি দেখায় write(#,<text you want to see>)), কিন্তু কাজ করে!


আপনি যুক্তি সংক্ষিপ্ত করা হয়েছে এ বিষয়টিও অপছন্দ করতে পারেন। এটি নিয়ন্ত্রণ করতে -sপ্যারামিটারটি ব্যবহার করুন যা প্রদর্শিত স্ট্রিংয়ের সর্বাধিক দৈর্ঘ্য নির্ধারণ করে।

এটি সমস্ত স্ট্রিম ক্যাচ করে, তাই আপনি যে কোনওরকম ফিল্টার করতে চাইতে পারেন:

strace -ewrite -p $PID 2>&1 | grep "write(1" 

কেবল বর্ণনাকারী 1 টি কল দেখায়। ডিফল্টরূপে STDERR এ লেখায় 2>&1যেমন straceSTDERR কে STDOUT এ পুনর্নির্দেশ করা হয়।


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

4
হ্যাঁ, এটি আংশিকভাবে কাজটি করে - তবে কিছু লোকের এই প্রশ্নটি পড়ার জন্য তাদের যা প্রয়োজন তা হল - কোনও প্রোগ্রামে কী ঘটছে তা ভুলভ্রান্তভাবে লিখতে বা অন্য কোনও কনসোলে লেখার জন্য দেখুন। প্রক্রিয়াটিতে এই প্রশ্নটি সন্ধান করার পরে আমি এটি খুঁজে পেয়েছি এবং ভেবেছিলাম এটি একটি দুর্দান্ত হ্যাক (কমপক্ষে আমার জন্য)। এবং যদি আমার চোখ আমাকে
দোষ

এটিও সম্ভব যা sudoপ্রয়োজন।
কলিডিয়ার

21

ভ্লাদারের (এবং অন্যদের) চমৎকার গবেষণা বন্ধ করে দেওয়া:

একই ডিরেক্টরিতে নিম্নলিখিত দুটি ফাইল তৈরি করুন, আপনার পথে কিছু বলুন say হোম / বিন:

নৈঃশব্দ.gdb, (ভ্লাদারের উত্তর থেকে):


p dup2(open("/dev/null",0),1)
p dup2(open("/dev/null",0),2)
detach
quit

এবং নীরবতা, ধারণ করে:


#!/bin/sh
if [ "$0" -a "$1" ]; then
 gdb -p $1 -x $0.gdb
else
 echo Must specify PID of process to silence >&2
fi

chmod +x ~/bin/silence  # make the script executable

এখন, পরের বার আপনি ফায়ারফক্সকে পুনর্নির্দেশ করতে ভুলে যান, উদাহরণস্বরূপ, এবং আপনার টার্মিনালটি অনিবার্য "(ফায়ারফক্স-বিন: 5117) এর সাথে বিশৃঙ্খলা পেতে শুরু করে: জিডিকে-সতর্কতা **: এক্সআইডি সংঘর্ষ, সামনের সমস্যা" বার্তা:


ps  # look for process xulrunner-stub (in this case we saw the PID in the error above)
silence 5117  # run the script, using PID we found

আপনি যদি দেখতে না চান তবে আপনি জিডিবি'র আউটপুটটিকে / dev / নালতেও পুনর্নির্দেশ করতে পারেন।


3
আমার জিডিবি (ভি 7.2) এর একটি সহজ বিকল্প রয়েছে --batch-silentযা আউটপুটকে দমন করে এবং কিছু ভুল হয়ে গেলে আপনাকে জিডিবি কনসোলে ডাম্প করে না (যেমন অনুপস্থিত প্রক্রিয়া)। বিটিডাব্লু, $!অতি সাম্প্রতিক পটভূমির কাজ বোঝায়, তবে আমি মনে করি না এটি স্ক্রিপ্টেই ব্যবহার করা যেতে পারে। আমি একজন ওরফে ব্যবহার করুন: alias silencebg='silence $!'
seanf

18

চলমান প্রক্রিয়া থেকে অন্য টার্মিনাল, ফাইল বা স্ক্রিনে আউটপুট পুনর্নির্দেশ:

tty
ls -l /proc/20818/fd
gdb -p 20818

জিডিবির ভিতরে :

p close(1)
p open("/dev/pts/4", 1)
p close(2)
p open("/tmp/myerrlog", 1)
q

বাশ টার্মিনাল থেকে একটি চলমান প্রক্রিয়া আলাদা করুন এবং এটিকে জীবিত রাখুন:

[Ctrl+z]
bg %1 && disown %1
[Ctrl+d]

ব্যাখ্যা:

20818 - প্রক্রিয়া পিআইডি
পি চালানোর কেবল উদাহরণ - জিডিবি কমান্ডের মুদ্রণ ফলাফল
বন্ধ (1) - স্ট্যান্ডার্ড আউটপুট / ডিভ / পিটিএস
/ 4 - টার্মিনালটি
বন্ধ করতে লিখুন (2) - বন্ধ ত্রুটি আউটপুট
/ টিএমপি / মাইর্ল্লগ - ফাইলটিতে
প্রশ্নে লিখুন - gdb
বিজি% 1 ছেড়ে দিন - ব্যাকগ্রাউন্ডে
% 1 টি থামানো চাকরীটি চালান - টার্মিনাল থেকে 1 টি কাজ আলাদা করুন


2
stdin(ফাইল বর্ণনাকারী 0) বন্ধ থাকলে এটি কাজ করবে না ।
pabouk

এটি আমার দিনকে বাঁচিয়েছিল। আমি এসএসএল-সেশনে প্রথম 10% সময় নিয়ে এক ঘন্টা সময় নিয়েছিলাম এবং আমি আমার ল্যাপটপটি আরও 10 ঘন্টা চালিয়ে রাখতে চাইনি। তবে আমি কি আপনার স্ট্রাইডারের জন্য পুনর্নির্দেশটি পড়া উচিত বলে ধরে নিচ্ছি p open("/tmp/myerrlog", 2)?
জেরার্ডভি

CentOS 6 এ চলমানটিতে খুব সামান্য সমস্যা ছিল - "/ tmp / myerrlog" ফাইলটি ইতিমধ্যে বিদ্যমান ছিল। স্পর্শ দিয়ে অবশ্যই এটি তৈরি করা তুচ্ছ ছিল।
ইবনেটার

3

আপনার প্রশ্নের সরাসরি উত্তর নয়, তবে এটি এমন একটি কৌশল যা আমি গত কয়েকদিন ধরে দরকারী হয়ে উঠছি: 'স্ক্রিন' ব্যবহার করে প্রাথমিক কমান্ডটি চালান, এবং তারপরে বিচ্ছিন্ন করুন।


2

এটি পূর্ববর্তী উত্তরের ভিত্তিতে বাশ স্ক্রিপ্ট অংশ যা কোনও উন্মুক্ত প্রক্রিয়া সম্পাদনের সময় লগ ফাইলকে পুনর্নির্দেশ করে, এটি logrotateপ্রক্রিয়াতে পোস্টস্ক্রিপ্ট হিসাবে ব্যবহৃত হয়

#!/bin/bash

pid=$(cat /var/run/app/app.pid)
logFile="/var/log/app.log"

reloadLog()
{
    if [ "$pid" = "" ]; then
        echo "invalid PID"
    else
        gdb -p $pid >/dev/null 2>&1 <<LOADLOG
p close(1)
p open("$logFile", 1)
p close(2)
p open("$logFile", 1)
q
LOADLOG
        LOG_FILE=$(ls /proc/${pid}/fd -l | fgrep " 1 -> " | awk '{print $11}')
        echo "log file set to $LOG_FILE"
    fi
}

reloadLog

1

ইতিমধ্যে চলমান প্রক্রিয়াটির স্ট্যান্ডার্ড আউটপুট / ইনপুট / ত্রুটি পুনর্নির্দেশের জন্য ডুপএক্স একটি সাধারণ * নিক্স ইউটিলিটি।

https://www.isi.edu/~yuri/dupx/


0

আপনি পুনঃনির্দেশ ব্যবহার করতে পারেন ( https://github.com/jerome-pouiller/reredirect/ )।

আদর্শ

reredirect -m FILE PID

এবং আউটপুট (স্ট্যান্ডার্ড এবং ত্রুটি) ফাইল এ লিখিত হবে।

পুনঃনির্দেশিত README আরও ব্যাখ্যা করে যে কীভাবে প্রক্রিয়াটির মূল অবস্থা পুনরুদ্ধার করা যায়, কীভাবে অন্য কমান্ডে পুনর্নির্দেশ করা যায় বা কেবল স্টডআউট বা স্টডারকে পুনর্নির্দেশ করা যায়।

reredirectএমন স্ক্রিপ্টও সরবরাহ করে যা relinkবর্তমান টার্মিনালে পুনর্নির্দেশ করতে দেয়:

relink PID
relink PID | grep usefull_content

(পুনঃনির্দেশে ডুপেক্সের অন্য উত্তরে বর্ণিত তুলনায় একই বৈশিষ্ট্য রয়েছে বলে মনে হয় তবে, এটি জিডিবির উপর নির্ভর করে না)।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.