সিগন্যাল ফরোয়ার্ড করতে ssh পান


22

আমি ssh এর মাধ্যমে সিগন্যাল (সাইন ইন সর্বাধিক গুরুত্বপূর্ণ) প্রেরণে সক্ষম হতে চাই।

এই আদেশ:

ssh server "sleep 1000;echo f" > foo

সার্ভারে ঘুম শুরু করবে এবং 1000 সেকেন্ড পরে এটি আমার লোকাল মেশিনে ফাইল ফুতে 'f \ n' রাখবে। আমি যদি সিটিআরএল-সি টি চাপি (অর্থাত্ এসআইএসএনটি এসএসএসে প্রেরণ করি) এটি এসএসএসকে মেরে ফেলবে, তবে এটি দূরবর্তী সার্ভারে ঘুমকে হত্যা করবে না। আমি এটি দূরবর্তী সার্ভারে ঘুমকে মেরে ফেলতে চাই।

সুতরাং আমি চেষ্টা করেছি:

ssh server -t "sleep 1000;echo f" > foo

তবে স্টিডিন যদি টার্মিনাল না হয় তবে আমি এই ত্রুটিটি পেয়েছি:

Pseudo-terminal will not be allocated because stdin is not a terminal.

এবং তারপরেও সাইন ইন এখনও ফরওয়ার্ড করা হয়নি।

সুতরাং আমি চেষ্টা করেছি:

ssh server -t -t "sleep 1000;echo f" > output

তবে foo এ আউটপুটটি 'f \ n' নয় বরং 'f \ r \ n' হয় যা আমার পরিস্থিতিতে বিপর্যয়কর (যেমন আমার আউটপুট বাইনারি ডেটা) is

উপরের অংশে আমি "স্লিপ 1000; ইকো এফ" ব্যবহার করি, তবে বাস্তবে যা ব্যবহারকারী সরবরাহ করে, তাতে এটি যে কোনও কিছু থাকতে পারে। তবে, যদি আমরা এটিকে "1000 1000; ইকো এফ" এর জন্য কাজ করতে পারি তবে আমরা সম্ভবত এটি সমস্ত বাস্তব পরিস্থিতিতে কাজ করতে পারি।

আমি অন্য প্রান্তে সিউডো-টার্মিনাল পাওয়ার বিষয়ে সত্যই চিন্তা করি না, তবে আমি আমার সাইন ইন ফরোয়ার্ডে এসএসএস পাওয়ার অন্য কোনও উপায় খুঁজে পাচ্ছি না।

অন্য উপায় আছে?

সম্পাদনা:

ব্যবহারকারী স্ট্যান্ডিনের থেকে বাইনারি ডেটা পড়ার জন্য কমান্ড দিতে পারে, যেমন:

seq 1000 | gzip | ssh server "zcat|bzip2; sleep 1000" | bzcat > foo

ব্যবহারকারী সিপিইউ নিবিড় এমন কমান্ড দিতে পারে যেমন:

ssh server "timeout 1000 burnP6"

Edit2:

আমার জন্য যে সংস্করণটি কাজ করে বলে মনে হচ্ছে তা হ'ল:

your_preprocessing |
  uuencode a | ssh -tt -oLogLevel=quiet server "stty isig -echoctl -echo ; uudecode -o - |
your_command |
  uuencode a" | uudecode -o - |
your_postprocessing

আমাকে সঠিক দিকে নির্দেশ করার জন্য ডিজিটাল_ইনফিনিটির ধন্যবাদ।


1
আমি আপনার প্রকৃত ব্যবহারের চিন্তা sshকি উদাহরণ দেখাতে চেয়েও বেশি জটিল করা আবশ্যক কারণ আপনার আচরণ আপনি একটি সহজ পুনর্বিন্যাস সাথে করতে চান পেতে পারেন,: sleep 1000 && ssh server "echo f" > foo(এটা হয়েছে হতে &&, না ;, যাতে হত্যা sleepপ্রতিরোধ ssh। চালু করা থেকে কমান্ড) যদি আমি ঠিক আছে, অনুগ্রহ করে আপনার উদাহরণগুলি আপনার প্রকৃত ব্যবহারের আরও প্রতিনিধি করুন, যাতে আরও ভাল উত্তর দেওয়া যায়।
ওয়ারেন ইয়ং

সঠিক: ঘুম এবং প্রতিধ্বনি আসলে ব্যবহারকারী সরবরাহ করা স্ক্রিপ্ট এবং আক্ষরিক ঘুম এবং প্রতিধ্বনি নয়। সুতরাং আমরা জানি না তারা কী করে এবং সবচেয়ে খারাপ ধারণা করা উচিত।
ওলে টাঞ্জ

সুও ... আপনি আরও একটি ভাল উদাহরণ কমান্ড নিয়ে আসছেন, তাই না? একটি যেখানে পুনরায় সাজানো সমস্যাটি সমাধান করে না? আপনি একটি ভাল প্রশ্ন জিজ্ঞাসা করুন, এবং আমি এটির উত্তর দেখতে চাই তবে আপনি যদি "তাই না করেন, তবে" একটি যুক্তিসঙ্গত জবাব হয় তবে আপনার উত্তর পাওয়ার সম্ভাবনা কম।
ওয়ারেন ইয়ং

ওহ ওয়ে, তা করবেন না;)
টিম

প্রশ্নে বর্ণিত হিসাবে: "" "উপরে আমি" স্লিপ 1000; ইকো এফ "ব্যবহার করি, কিন্তু বাস্তবে যা ব্যবহারকারী দ্বারা সরবরাহ করা হয়, সুতরাং এটিতে" "" কিছু থাকতে পারে
ওলে টেঞ্জ

উত্তর:


10

সংক্ষিপ্ত উত্তর:

ssh -t fs "stty isig intr ^N -echoctl ; trap '/bin/true' SIGINT; sleep 1000; echo f" > foo

এবং প্রোগ্রামটি CTRL + N দ্বারা বন্ধ করুন।

দীর্ঘ ব্যাখ্যা:

  1. একে অপরের সাথে সংঘর্ষ না হওয়ার জন্য আপনার সার্ভার বা স্থানীয় বাধা চরিত্রটি পরিবর্তন করতে আপনাকে অবশ্যই sttyবিকল্পটি ব্যবহার intrকরতে হবে । উপরের কমান্ডটিতে আমি সার্ভারের বাধা চরিত্রটিকে CTRL + N এ পরিবর্তন করেছি। আপনি আপনার স্থানীয় বাধা চরিত্র পরিবর্তন করতে পারেন এবং কোনও পরিবর্তন ছাড়াই সার্ভারের একটি ছেড়ে যেতে পারেন।
  2. আপনি যদি না চান তবে বাধা চরিত্রটি আপনার আউটপুট (এবং অন্য কোনও নিয়ন্ত্রণ অক্ষর) ব্যবহারের মধ্যে থাকে stty -echoctl
  3. আপনাকে অবশ্যই নিশ্চয়তা দিতে হবে যে sshd দ্বারা চালিত সার্ভার ব্যাশে নিয়ন্ত্রণ অক্ষরগুলি স্যুইচ করা আছে। আপনি যদি না করেন তবে লগআউট করার পরেও এখনও প্রক্রিয়াগুলি ঝুলতে পারে।stty isig
  4. আপনি আসলে খালি বিবৃতি দিয়ে SIGINTসংকেত ধরেন catch trap '/bin/true' SIGINTফাঁদ ছাড়া আপনার শেষের দিকে সিগিন্ট সিগন্যালের পরে কোনও স্টডআউট পাবেন না have

বাইনারি ইনপুটটি সুন্দরভাবে মোকাবেলা করবে না বলে মনে হচ্ছে: seq 1000 | gzip | ssh -t -t সার্ভার "stty isig intr ^ N -echoctl; trap '/ bin / true' SignINT; ঘুম 1; zcat | bzip2" | bzcat> foo;
ওলে টাঞ্জ

আপনি যদি কনসোলের জন্য এসএসএসের জন্য স্ট্যান্ডার্ড ইনপুট সেট করে থাকেন তবে কনসোল দিয়ে বাধা দিতে পারবেন না। এই ক্ষেত্রে আপনাকে স্টিডিন স্ট্রিম দ্বারা বাধা দিতে হবে।
ডিজিটাল_ইনফিনিটি

আমি দেখেছি যে এটি seq 1000 | gzip | ssh -tt dell-test "zcat|bzip2" | bzcat > fooখুব বেশি কাজ করে না। এই কমান্ডটির কাজ করার জন্য আমাদের অপসারণ করতে হবে -tt। সুতরাং সিউডো টার্মিনাল বরাদ্দ সম্ভবত
স্টিন

আমি ইউয়েনকোড চেষ্টা করেছিলাম। এই সংস্করণে এটি কাজ করে না: cat foo.gz | perl -ne 'মুদ্রণ প্যাক ("আপনি", $ _)' | ssh -t -t সার্ভার 'পার্ল -ne "প্রিন্ট আনপ্যাক (\" u \ ", \ $ _)" | zcat | gzip | perl -ne "প্রিন্ট প্যাক (\" u \ ", \ $ _)" '| perl -ne 'মুদ্রণ আনপ্যাক ("আপনি", $ _)'> foo2.gz
ওলে

1
আমি এই আছে: (sleep 1; seq 1000 ) | gzip | uuencode bin | ssh -tt dell-test "stty isig intr ^N -echoctl -echo ; trap '/bin/true' SIGINT; sleep 1; uudecode -o /dev/stdout | zcat |bzip2 | uuencode bin2 " | uudecode -o /dev/stdout | bzcat >foo। যদিও বিঘ্নিত চরিত্রটি কাজ করে না - স্টিডিন ব্যস্ত থাকাকালীন আমাদের বিঘ্নিত চরিত্রের জন্য কিছু সংক্রমণ পদ্ধতি প্রয়োজন ।
ডিজিটাল_ইনফিনিটি

3

আমি সমস্ত সমাধান চেষ্টা করেছিলাম এবং এটিই সেরা:

ssh host "sleep 99 < <(cat; kill -INT 0)" <&1

/programming/3235180/starting-a-process-over-ssh-using-bash-and-then-killing-it-on-sigint/25882610#25882610


sleepএটি সংযোগটি হারিয়ে যাওয়ার ক্ষেত্রে প্রক্রিয়াটি থামায় না ।
13:53

যখন সংযোগটি হারিয়ে যায় তখন স্টিডিন বিড়ালটিকে ব্লক করে ভেঙে ফেলা হবে যা প্রক্রিয়া গোষ্ঠীকে হত্যা করবে। আপনার কাজের জন্য যে ইন্টিস্ট্রাপ সিগন্যাল যথেষ্ট ভাল কিনা তা ভিন্ন প্রশ্ন।
এরিক উডরুফ

এটা যথেষ্ট জন্য ভাল করা sleepউচিত, তাই না? আমি এর date >> /tmp/killedপরে কিছু যুক্ত করেছি cat, তবে এটি ট্রিগার হয়নি। কিছু সময়সীমা জড়িত আছে? আমি সাধারণত জেডএস ব্যবহার করছি, তবে এটি রিমোট লগইন শেল হিসাবে ব্যাশের সাথেও পরীক্ষা করেছি।
14:43

আমি মনে করি আপনি সংযোগের সময়সীমা শেষ করতে পারেন।
এরিক

এটি নিয়ন্ত্রণ করার জন্য কি সেটিংস আছে? ক্লায়েন্ট পক্ষের -o ServerAliveInterval=3 -o ServerAliveCountMax=2জন্য এটি দ্রুত সনাক্ত করতে দেয় তবে সার্ভার সাইডের জন্য কি কিছু আছে?
নীল রঙের

2

আমি মনে করি আপনি সার্ভারে যে প্রক্রিয়া চালাচ্ছেন তার পিআইডি খুঁজে পেতে এবং অন্য একটি sshকমান্ড ব্যবহার করে একটি সংকেত প্রেরণ করতে (যেমন ssh server "kill -2 PID":) could

আমি আলাদা পদ্ধতিতে চলমান অ্যাপ্লিকেশনগুলিতে পুনরায় কনফিগারেশন সংকেত প্রেরণের জন্য এই পদ্ধতিটি ব্যবহার করি (আমার অ্যাপ্লিকেশনগুলি SIGUSR1 ধরে এবং একটি কনফিগার ফাইল পড়ে) read আমার ক্ষেত্রে পিআইডি সন্ধান করা সহজ, কারণ আমার অনন্য প্রক্রিয়ার নাম রয়েছে এবং আমি পিআইডি খুঁজে পেতে পারি একটি psঅনুরোধ প্রেরণ করে ssh


রিমোটে চলমান প্রোগ্রামটির পিআইডি সন্ধানের বুলেট প্রুফের উপায় আমি দেখতে পাচ্ছি না। মনে রাখবেন এটি ব্যবহারকারী দিয়েছেন। এটি হতে পারে: ssh সার্ভার 'এক্সিকিউটিভ $ (ইকো ফাইরসিআরসি 1000 | / usr / গেমস / রট 13)'
ওলে

1

সমাধানটি বিবর্তিত হয়েছে http://www.gnu.org/software/parallel/parallel_design.html#Remote-Ctrl-C-and-standard-error-stderr

$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)

0

----- কমান্ড.শ

#! /bin/sh
trap 'trap - EXIT; kill 0; exit' EXIT
(sleep 1000;echo f) &
read ans

----- স্থানীয় টার্মিনালে

sleep 864000 | ssh -T server command.sh > foo

নমস্কার! আমি মনে করি আপনি প্রাসঙ্গিক বলে মনে করেন, এটি কীভাবে কাজ করে তত বিশদভাবে ব্যাখ্যা দিয়ে আপনি আপনার উত্তরটি আরও কার্যকর করতে পারবেন। নতুন তথ্য toোকাতে এটি সম্পাদনা করতে দ্বিধা করবেন না।
ধাগ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.