এসএসএইচ: স্টিডিন, স্টাডআউট, স্টার্ডার ছাড়াও অতিরিক্ত "পাইপ" এফডিএস সরবরাহ করুন


12

যখন SSH সহযোগে একটি হোস্টে সংযুক্ত হওয়ার, সাধারণত তিনটি "পাইপ" হোস্ট এবং গেস্টের মধ্যে প্রদান করা হয়, জন্য stdin, stdoutএবং stderr

অতিরিক্ত ফাইল বর্ণনাকারীদের ( 3এবং সামনের) জন্য ফরওয়ার্ড তৈরি করার জন্য কি কোনও কমান্ড-লাইন বিকল্প রয়েছে ?

উদাহরণস্বরূপ, আমি করতে চাই

ssh --forwardfd=10:3 remotehost 'echo test >&3'

যা স্থানীয়ভাবে খোলা ফাইল বর্ণনাকারী 10 এ 'পরীক্ষা' মুদ্রণ করবে।


2
সম্ভবত closefrom(STDERR_FILENO + 1)ওপেনএসএসএইচ উত্স কোডের অধীনে বিভিন্ন কল দেওয়া কৌতুকপূর্ণ উত্স সম্পাদনা ছাড়াই নয় । আপনি এটি করার জন্য কী চেষ্টা করছেন?
ট্রিগার করুন

প্রোটোকলটি stdin/ out/ এর পাশাপাশি অতিরিক্ত স্ট্রিমগুলি টানেলিং সমর্থন করে errতবে আফিক, কোনও সার্ভার / ক্লায়েন্ট সেই বৈশিষ্ট্যটি কোনওভাবে সমর্থন সরবরাহ করে না।
সালভা

@ থ্রিগ্রি ওপি নয়, এবং এটি অনেক দিন হয়ে গেছে তবে আপনি কী এখনও জানতে আগ্রহী হন যে এটি কী জন্য কার্যকর হতে পারে, আমি এখানে যা আশা করছিলাম সেটি কীভাবে এসএসএসের মাধ্যমে পাইপ করা যায় তার একটি সূত্র ছিল, বাশ এবং একটি স্ক্রিপ্ট স্ক্রিপ্টের জন্য স্টিডিন। এর সদৃশ কিছু:infinite-output-cmd | ssh user@host bash /proc/self/fd/3 3< local-script-to-execute-remotely.sh
জোলে

@ থ্রিগ আমার কাছে এমন ঘটে যে এর মতো কোনও কিছুর --forwardfdপ্রয়োজন হয় না। sshঅন্য কোনও জিনিস খোলার আগে ওপেন ফাইল বর্ণনাকারীগুলি কী তা পরীক্ষা করে দেখতে পারে এবং এগুলি দূরবর্তী পার্শ্বে একই ফাইল বর্ণনাকারীর কাছে স্বয়ংক্রিয়ভাবে ফরোয়ার্ড করতে পারে। এটি আমার উদাহরণের মতো সম্পূর্ণ স্বচ্ছ হতে পারে। আমি ভাবছি যে এটির জন্য প্যাচ করা কতটা কঠিন ssh। যেমনটি আপনি বলেছেন, এর পিছনে কারণগুলির উপর নির্ভর করে এটি জটিল হতে পারে closefrom(STDERR_FILENO + 1)
জোল

উত্তর:


6

আপনি সকেট ফরোয়ার্ডিং ব্যবহার করে এটি করতে পারেন, যা ওপেনশ্যাশ-6..7 থেকে পাওয়া যায়। এটি এক ধরণের পাইপ। এই কৌশলটি উদাহরণস্বরূপ এখানে বর্ণিত হয়েছে: http://www.25thandclement.com/~william/projects/streamlocal.html

আপনি আপনার ডেটার জন্য দ্বি-দিকের রুট অর্জন করবেন। মাইএসকিএল সহ উদাহরণ রয়েছে:

আপনার স্থানীয় উদাহরণের সাথে রিমোট সার্ভারে প্রক্সি মাইএসকিউএল ক্লায়েন্ট সংযোগগুলি:

ssh -R/var/run/mysql.sock:/var/run/mysql.sock \
    -R127.0.0.1:3306:/var/run/mysql.sock somehost 

1

আমি নিশ্চিত এটি সম্ভব হওয়া উচিত। আমি কেবলমাত্র এমন একটি হ্যাকের পরামর্শ দিতে পারি যেখানে আপনি প্রতিটি ক্ষেত্রে অতিরিক্ত সংখ্যক এসএস সংযোগ ব্যবহার করেন ফাইল বর্ণনাকারীর একজোড়া carry উদাহরণস্বরূপ কনসেপ্ট স্ক্রিপ্টের নীচের প্রমাণটি স্থানীয় এফডিএস 5 এবং 6 টি রিমোট স্টিডিন এবং স্টাডআউটের সাথে সংযুক্ত করার জন্য একটি ডামি কমান্ড (স্লিপ) চালানোর জন্য প্রথম ssh করে, অনুমান করে যে এই এফডিএসটি আপনি স্বাভাবিক 0,1 এ যুক্ত করতে চান, 2।

তারপরে আসল এসএসএস সম্পন্ন হবে এবং রিমোটে এটি অন্য এসএসএসের স্টিডিন এবং স্টাডাউটের সাথে দূরবর্তী এফডিএস 5 এবং 6 টি সংযুক্ত করে।

যেমন একটি উদাহরণ হিসাবে, এই স্ক্রিপ্টটি একটি গিজিপযুক্ত ম্যান পৃষ্ঠাটি রিমোটের কাছে দিয়ে যায় যা এটি উন্মুক্ত করে এবং এটি মানুষের মাধ্যমে চালায়। আসল ssh এর stdin এবং stdout অন্যান্য জিনিসগুলির জন্য এখনও উপলব্ধ।

#!/bin/bash
exec 5</usr/share/man/man1/ssh.1.gz 6>/tmp/out6 # pretend need 5 and 6

ssh remote 'echo $$ >/tmp/pid; exec sleep 99999' <&5 >&6 &
sleep 1 # hack. need /tmp/pid to be set

ssh remote '
  pid=$(</tmp/pid) 
  exec 5</proc/$pid/fd/0 6>/proc/$pid/fd/1
  echo start
  gzip -d <&5 | man /dev/stdin >&6
  echo stop
  kill -hup $pid
'
wait
less /tmp/out6

1

@ জাকুজে-র উত্তরের সমস্যাটি হ'ল: এটি কেবল সকেটগুলির সাথেই কাজ করে , তবে আপনি তাদের সাথে ফাইল প্রত্যাশার মানক ইউনিক্স সরঞ্জামগুলি ব্যবহার করতে পারবেন না :

ssh -R/tmp/sock.remote:/tmp/sock.local "$HOST" 'LANG=C cat >/tmp/sock.remote'

bash: /tmp/sock.remote: এ জাতীয় কোনও ডিভাইস বা ঠিকানা নেই

এছাড়াও সমস্যা আছে যে স্থানীয় সকেট ফাইলটি দূরবর্তী হোস্টে মুছে ফেলা হয় না; এর পরে যখন আপনি একই কমান্ডটি চালান, আপনি একটি সতর্কতা পান এবং সকেটটি সঠিকভাবে পুনরায় তৈরি হয় না। আপনি সেই পুরানো সকেটটি লিঙ্ক -o StreamLocalBindUnlink=yesকরার বিকল্পটি দিতে পারেন ssh, তবে আমার পরীক্ষাগুলিতে এটি যথেষ্ট ছিল না; সেই বিকল্পটি কাজ করার জন্য আপনাকে সম্পাদনা করতে sshd_configহবে StreamLocalBindUnlink=yes

কিন্তু আপনি ব্যবহার করতে পারেন socatবা netcatবা অনুরূপ কোন সমর্থনকারী টুল ইউনিক্স স্থানীয় সকেট ( netcat-traditionalহয় না যথেষ্ট!) ফাইল ট্রান্সফার জন্য স্থানীয় সকেট ফরওয়ার্ডিং ব্যবহার করার জন্য:

# start local process listening on local socket, which receives the data when ssh opens the connections and saves it to a local file
nc -l -N -U /tmp/sock.local >/tmp/file.local &
# connect to remote $HOST and pipe the remote file into the remote socket end
ssh \
 -o ExitOnForwardFailure=yes \
 -o StreamLocalBindUnlink=yes \
 -R /tmp/sock.remote:/tmp/sock.local \
 "$HOST" \
 'nc -N -U /tmp/sock.remote </tmp/file.remote'

আপনি ইন্টারেক্টিভ কমান্ডগুলিও চালাতে পারেন, ssh -tসেক্ষেত্রে আপনার টিটিওয়াই বরাদ্দ দেওয়ার জন্য ব্যবহার করা উচিত ।

এই সমাধানটির সাথে সমস্যাটি হ'ল আপনাকে অবশ্যই ইউনিক্স স্থানীয় সকেটের পাথগুলি হার্ড-কোড করতে হবে: স্থানীয়ভাবে এটি এতটা সমস্যা নয় যেহেতু আপনি $$প্রক্রিয়া অনুসারে বা ব্যবহারকারীকে একটি অস্থায়ী ডিরেক্টরি হিসাবে অনন্য করে তোলার পথে অন্তর্ভুক্ত করতে পারেন , তবে রিমোট-এন্ড আপনি আরও ভাল করে বিশ্ব-রচনামূলক ডিরেক্টরিটি ব্যবহার করবেন না /tmp/যেমনটি আমি আমার উদাহরণে করি। sshসেশন শুরু হওয়ার পরে ডিরেক্টরিটি ইতিমধ্যে উপস্থিত থাকতে হবে । এবং সকেট ইনোডটি সেশনটি বন্ধ হওয়ার পরেও থাকবে, সুতরাং "OME HOME / .ssh। Like" এর মতো কিছু ব্যবহার করে আপনার ডিরেক্টরিটি সময়ের সাথে সাথে মৃত আইনের সাথে বিশৃঙ্খলা করবে।

আপনি আবদ্ধ টিসিপি সকেটগুলিও ব্যবহার করতে পারেন localhost, যা আপনাকে মৃত আইনোডগুলি দিয়ে আপনার ফাইল সিস্টেমগুলিকে গোলমাল করা থেকে বাঁচাতে পারে, তবে তাদের সাথে এখনও আপনাকে একটি (অনন্য) অব্যবহৃত পোর্ট নম্বর চয়ন করতে সমস্যা করতে হবে। তাই এখনও আদর্শ নয়। ( sshগতিশীলভাবে বন্দর বরাদ্দ করার কোড রয়েছে তবে আমি দূরবর্তী হোস্টে সেই তথ্য পুনরুদ্ধার করার কোনও উপায় পাইনি))

সম্ভবত ফাইল কপি করার সবচেয়ে সহজ সমাধান ব্যবহার করতে SSH বিল্ট-ইন-এর জন্য সংযোগ ভাগ কার্যকারিতা এবং একটি করতে scpবা sfrpযখন আপনার ইন্টারেক্টিভ সেশান তথাপি সমান্তরাল চলমান কমান্ড। দেখুন কপি SSH সাথে স্থানীয় সিস্টেমের জন্য একটি ফাইল ফিরে

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