stderr over ssh -t


11

Stderr হবে এই আউটপুট পাঠায়, কিন্তু সঞ্চারিত করে না Ctrl+ + C(অর্থাত Ctrl+ + Cমেরে ফেলবে sshকিন্তু দূরবর্তী sleep):

$ ssh localhost 'sleep 100;echo foo ">&2"'

এটি Ctrl+ C(অর্থাত্ Ctrl+ Cমেরে ফেলবে sshএবং দূরবর্তী sleep) প্রচার করে তবে STDERR কে STDOUT এ প্রেরণ করে:

$ ssh -tt localhost 'sleep 100;echo foo ">&2"'

আমি এখনও দ্বিতীয়টিকে কীভাবে STDERR এ এসটিডিআরআর আউটপুট প্রেরণ করতে বাধ্য করতে পারি, এখনও Ctrl+ প্রচার করার সময় C?

পটভূমি

জিএনইউ সমান্তরাল Ctrl+ প্রচার করতে 'ssh -tt' ব্যবহার করে C। এটি দূরবর্তীভাবে চলমান কাজগুলিকে হত্যা সম্ভব করে তোলে। তবে এসটিডিআরআরে প্রেরিত ডেটাগুলি প্রাপ্তির শেষে এসটিডিআরআরে যেতে থাকবে।

উত্তর:


5

আমি মনে করি না আপনি এটিকে পেতে পারেন।

সঙ্গে -tt, sshdএকটি সিউডো-টার্মিনাল ও স্লেভ অংশ stdin, stdout- এ এবং শেল দূরবর্তী কমান্ড executes এর দ্বারা stderr তোলে spawns।

sshdসিডো-টার্মিনালের মাস্টার অংশে তার (একক) এফডি থেকে কী আসছে তা পড়ে এবং এটি (একক চ্যানেলের মাধ্যমে) sshক্লায়েন্টকে প্রেরণ করে । স্টাডারের বাইরে নেই বলে দ্বিতীয় চ্যানেল নেই -t

তদুপরি লক্ষ করুন যে সিউডো-টার্মিনালের টার্মিনাল লাইন শৃঙ্খলা আউটপুট পরিবর্তন করতে পারে (এবং পূর্বনির্ধারিতভাবে হবে)। উদাহরণস্বরূপ, এলএফ স্থানীয় টার্মিনালে নয়, সেখানে সিআরএলএফে রূপান্তরিত হবে, সুতরাং আপনি আউটপুট পোস্ট-প্রসেসিং অক্ষম করতে চাইতে পারেন।

$ ssh  localhost 'echo x' | hd
00000000  78 0a                                             |x.|
00000002
$ ssh -t localhost 'echo x' | hd
00000000  78 0d 0a                                          |x..|
00000003
$ ssh -t localhost 'stty -opost; echo x' | hd
00000000  78 0a                                             |x.|
00000002

ইনপুট সাইডে আরও অনেক কিছু ঘটবে (যেমনটি এমন ^Cচরিত্রের মতো যা একটি সিগিন্টের কারণ হয়ে দাঁড়ায়, তবে অন্যান্য সংকেতগুলি, প্রতিধ্বনি এবং ক্যানোনিকাল মোড লাইন সম্পাদকের সাথে জড়িত সমস্ত হ্যান্ডলিং )।

আপনি সম্ভবত স্টাডারকে একটি ফিফোতে পুনর্নির্দেশ করতে এবং এটি একটি দ্বিতীয় ব্যবহার করে পুনরুদ্ধার করতে পারেন ssh:

ssh -tt host 'mkfifo fifo && cmd 2> fifo' &
ssh host 'cat fifo' >&2

তবে সেরা আইএমও হ'ল -tসম্পূর্ণরূপে ব্যবহার এড়ানো উচিত। এটি সত্যই কেবল আসল টার্মিনাল থেকে ইন্টারেক্টিভ ব্যবহারের জন্য।

দূরবর্তী প্রান্তটি সংযোগ বন্ধ হতে দিতে কোনও ^ সি ট্রান্সমিশনের উপর নির্ভর করার পরিবর্তে, আপনি একটি মোড়ক ব্যবহার করতে পারেন poll()যা নিহত sshবা বন্ধ সংযোগ সনাক্ত করতে একটি করে ।

হতে পারে এর মতো কিছু (সরলীকৃত, আপনি কিছু ত্রুটি পরীক্ষা করে যুক্ত করতে চান):

LC_HUP_DETECTOR='
  use IO::Poll;
  $SIG{CHLD} = sub {$done = 1};
  $p = IO::Poll->new;
  $p->mask(STDOUT, POLLIN);
  $pid=fork; unless($pid) {setpgrp; exec @ARGV; die "exec: $!\n"}
  $p->poll;
  kill SIGHUP, -$pid unless $done;
  wait; exit ($?&127 ? 128+($?&127) : 1+$?>>8)
' ssh host 'perl -e "$LC_HUP_DETECTOR" some cmd'

$p->mask(STDOUT, POLLIN)উপরে নিরীহ মনে হতে পারে, কিন্তু ধারণা (বন্ধ করে দেওয়া হয় stdout- এ তে পাইপের পড়া শেষ) একটি নীচ hup থেকে ইভেন্টের জন্য অপেক্ষা করতে হয়। অনুরোধ করা মুখোশ হিসাবে পোলহাপ উপেক্ষা করা হবে। POLLHUP শুধুমাত্র meaningfull একটি ফিরে ঘটনা হিসাবে (বলতে যে লেখা শেষ বন্ধ করে দেয়া হয়েছে)।

ইভেন্ট মাস্কের জন্য আমাদের একটি শূন্য-মান দিতে হবে। আমরা যদি ব্যবহার করি 0, perlকলও করি না poll। সুতরাং এখানে আমরা পলিং ব্যবহার করি।

লিনাক্সে, আপনি যা যা অনুরোধ করুন, পাইপটি নষ্ট হয়ে গেলে, পোল () POLLERR প্রদান করে।

সোলারিস এবং ফ্রিবিএসডি-তে, যেখানে পাইপগুলি দ্বি নির্দেশমূলক হয়, যখন পাইপের পাঠ শেষ হয় (যা সেখানে লেখার শেষও হয়) বন্ধ হয়ে যায়, তখন এটি পলহাপ (এবং ফ্রিবিএসডি-তে পলিন) দিয়ে ফিরে আসে, যেখানে আপনাকে পলিনের জন্য অনুরোধ করতে হবে অন্যথায় $p->poll()না আসতে)।

এই তিনটি অপারেটিং সিস্টেমের বাইরে অন্যথায় এটি কতটা পোর্টেবল তা আমি বলতে পারি না।


আমি আপনার ধারণাটি পছন্দ করি তবে '-টি' সেট না করা পর্যন্ত আমি আপনার মোড়কে কোনও সংকেত সনাক্ত করতে পারি না। এটি কাজ করে: parallel --tag -j1 'ssh -tt localhost perl/catch_wrap perl/catch_all_signals & sleep 1; killall -{} ssh' ::: {1..31}তবে '-tt' সরান এবং তারপরে এটি কার্যকর হয় না।
ওলে টাঞ্জ

@ ওলেট্যাঞ্জ এসএইচইচইপকে রিমোট জব প্রেরণ করা হবে যখন এসএসএস মারা যায় (এসএসএস সংযোগ হ্যাং-আপের পরে) আপনার ক্যাচ_ল_সিগন্যালগুলি কী করে তা আমি জানি না, তবে এগুলি কেবল সইগআপ এবং কেবল এসএসএস সংযোগ হ্রাস হওয়ার পরে (সুতরাং এটি স্টাডাউটে কোনও কিছু প্রিন্ট করলে আপনি তা দেখতে পাবেন না)।
স্টাফেন চেজেলাস

ক্যাচ_ল_সিগন্যালগুলি কোনও ফাইলে সমস্ত সংকেত লগ করে এবং যেমন উল্লিখিত হয়েছে এটি '-tt' দিয়ে কাজ করে তবে ব্যর্থ হয়। অন্য কথায়: এসএস মারা গেলে এটি ক্যাচ_আরপ থেকে সাইনআপ গ্রহণ করে না।
ওলে টাঞ্জ

এখনও -ttআপনার সম্পাদনার পরে কাজ করে with দয়া করে মনে রাখবেন আপনি যদি সমান্তরাল মাধ্যমে কমান্ডটি চালনা না করেন তবে ssh আপনাকে যে টার্মিনালটি চালাবে সেটির উত্তরাধিকারী হবে।
ওলে টাঞ্জ

@ ওলেট্যাঞ্জ, আমি পুনরুত্পাদন করতে পারি না, এটি আমার পক্ষে কাজ করে, আপনি যে পোস্ট করেছেন কোড দিয়ে তা পরীক্ষা করেছেন? দয়া করে আপনার ক্যাচ_আর্যাপ এবং ক্যাচ_আল_ সিগন্যালগুলি কোথাও পোস্ট করুন যাতে আমি একবার দেখতে পারি। সাথে -t, আমি এটি কাজ না আশা করি ।
স্টাফেন চেজেলাস

1

অন্যান্য প্ল্যাটফর্মে এটিকে কাজ করার জন্য এটি চূড়ান্ত সমাধানে পরিণত হয়েছে। এটি পরীক্ষা করে যে এসএস ক্লায়েন্টটি সংযোগ বিচ্ছিন্ন হয়েছে এবং এভাবে পিতামাতারা পিড 1 হয়েছেন:

$SIG{CHLD} = sub { $done = 1; };
$pid = fork;
unless($pid) {
    # Make own process group to be able to kill HUP it later
    setpgrp;
    exec $ENV{SHELL}, "-c", ($bashfunc."@ARGV");
    die "exec: $!\n";
}
do {
    # Parent is not init (ppid=1), so sshd is alive
    # Exponential sleep up to 1 sec
    $s = $s < 1 ? 0.001 + $s * 1.03 : $s;
    select(undef, undef, undef, $s);
} until ($done || getppid == 1);
# Kill HUP the process group if job not done
kill(SIGHUP, -${pid}) unless $done;
wait;
exit ($?&127 ? 128+($?&127) : 1+$?>>8)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.