একাধিক ফাইল স্টিডিনের মাধ্যমে পাস করা (ওভার এসএসএস)


15

আমার একটি রিমোট হোস্টে একটি প্রোগ্রাম রয়েছে, যার প্রয়োগের জন্য আমাকে স্বয়ংক্রিয় প্রয়োজন। কমান্ডটি একই মেশিনে প্রোগ্রামটি সম্পাদন করে, এরকম কিছু দেখায়:

/path/to/program -a file1.txt -b file2.txt

এই ক্ষেত্রে, file1.txtএবং file2.txtপ্রোগ্রামের মধ্যে সম্পূর্ণ আলাদা জিনিসগুলির জন্য ব্যবহৃত হয়, তাই আমি কেবল catতাদের একসাথে করতে পারি না । যাইহোক, আমার ক্ষেত্রে, file1.txtএবং file2.txtআমি যে প্রোগ্রামটিতে প্রবেশ করতে চাই তা কেবলমাত্র আমার ডিভাইসে উপস্থিত রয়েছে, যে হোস্টটিতে আমাকে প্রোগ্রামটি চালানো দরকার সেখানে নয়। আমি জানি যে আমি এসএসএইচ এর মাধ্যমে কমপক্ষে একটি ফাইল দিয়ে যেতে পারি stdin:

cat file1.txt | ssh host.name /path/to/program -a /dev/stdin -b file2.txt

তবে, যেহেতু আমাকে হোস্টে ফাইল সঞ্চয় করার অনুমতি নেই, আমার file2.txtপাশাপাশি সেখানেও যাওয়ার একটি উপায় প্রয়োজন । আমি ভাবছি পরিবেশের পরিবর্তনশীলগুলির অপব্যবহারের মাধ্যমে catএবং sedএকসাথে সৃজনশীল ব্যবহারের মাধ্যমে এটি সম্ভব হতে পারে তবে আমি কীভাবে সরঞ্জামগুলি এটি সম্পাদন করতে ব্যবহার করব তা বোঝার জন্য আমি যথেষ্ট সরঞ্জামগুলি জানি না। এটা কি doable, এবং কিভাবে?


2
catএবং sedএখানে সমাধান নয়।
স্লিক্স

সম্ভবত আমি মাউন্ট করতে সক্ষম হব, তবে প্রক্সি এবং সুরক্ষা সীমাবদ্ধতার কারণে আমি নিশ্চিত যে আমি এটি থেকে সরে যেতে সক্ষম হব না।
সবুজ পোশাকওয়ালা গাই

আপনার কাছে কি দূরবর্তী মেশিনে কোনও এসএস ফোল্ডার মাউন্ট করার অনুমতি রয়েছে?
স্লিক্স

1
যদি আপনি রিমোট মেশিন থেকে আপনার স্থানীয় একটিতে কোনও এসএস সেশন খুলতে পারেন, তবে এসএসএইচ ফোল্ডারটি মাউন্ট করার জন্য নেটওয়ার্ক স্তরে কোনও সমস্যা নেই।
স্লিক্স

আপনি কি ফরওয়ার্ডিং করতে পারবেন? স্থানীয় এবং দূরবর্তী প্রান্তে আপনার কী সিস্টেম এবং শেল রয়েছে?
মশবি

উত্তর:


18

আপনার প্রোগ্রামটিতে আর্গুমেন্ট হিসাবে দেওয়া ফাইলগুলি যদি টেক্সট ফাইল হয় এবং আপনি তাদের বিষয়বস্তু নিয়ন্ত্রণ করতে সক্ষম হন (আপনি তাদের মধ্যে এমন একটি লাইন জানেন যা তাদের মধ্যে ঘটে না) তবে আপনি এখানে একাধিক-নথি ব্যবহার করতে পারেন:

{
    echo "cat /dev/fd/3 3<<'EOT' /dev/fd/4 4<<'EOT' /dev/fd/5 5<<'EOT'"
    cat file1
    echo EOT
    cat file2
    echo EOT
    cat file3
    echo EOT
} | ssh user@host sh

এখানে catএকটি নমুনা কমান্ড যা ফাইলের নামগুলি আর্গুমেন্ট হিসাবে গ্রহণ করে। এটি পরিবর্তে হতে পারে:

echo "/path/to/prog -a /dev/fd/3 3<<'EOT' -b /dev/fd/4 4<<'EOT'

প্রতিটি EOTফাইলকে যথাক্রমে ঘটে না এমন কিছু দিয়ে প্রতিস্থাপন করুন ।


1
এই পদ্ধতির বেশ চালাক! যদি ফাইলগুলি পাঠ্য না হয় তবে আপনি এগুলি এনকোড / ডিকোড করতে পারেন বেস 64 বা এমনকি ভাল 'ইউউনকোডের মতো কিছু দিয়ে ... খুব সুন্দর!
ফিলাব্রেন্ডেন

3
নোট করুন যে বেশ কয়েকটি (সর্বাধিক) প্রয়োগগুলি এখানে অস্থায়ী ফাইলগুলি ব্যবহার করে নথিগুলি প্রয়োগ করে, তাই তারা যদি দূরবর্তী হোস্টে ফাইলগুলি সংরক্ষণ করার অনুমতি না দেয় তবে ওপিতে এটি কাজ করতে পারে না।
স্টাফেন চেজেলাস

2
dash( /bin/shডেবিয়ান, উবুন্টু, ইত্যাদি), busybox sh, /bin/shFreeBSD থেকে এবং yashঅস্থায়ী ফাইল এখানে-নথি জন্য ব্যবহার করবেন না। আমি আসলে এটি কেবল পঠনযোগ্য ক্রোট দিয়ে পরীক্ষা করেছি। অবশ্যই, /dev/fd/ফাইলগুলি উপলভ্য থাকতে হবে - স্টকটিতে কেবল ফ্রিবিএসডি সিস্টেম /dev/fd/0-2রয়েছে, তাই fdescfsমাউন্ট করতে হবে /dev/fd
মশবী

1
আমি ASCII তথ্য বিভাজকগুলির একটি অনুরাগী , যা কোনও বাধা ছাড়াই ক্ষেত্রগুলি সীমিত করার জন্য ডিজাইন করা হয়েছে। U+001C"ইনফরমেশন সেপারেটর ফোর" (ফাইল বিভাজক, এফএস) এবং এই ক্ষেত্রে আদর্শ, যদিও বাইনারি ফাইলগুলি এটি কাকতালীয়ভাবে ব্যবহার করতে পারে। অতএব, আমি সামঞ্জস্যের জন্য EOT="$(printf $'\x1c')"উন্নত শেলগুলিতে প্রস্তাব দেব EOT="$(awk 'BEGIN{printf"%c",28}')"। আপনি এটি স্থাপন করার সময় আপনার এটিকে উদ্ধৃত করতে হবে, যেমন echo "$EOT$EOT$EOT"(বাইনারি ফাইলের মিলের প্রতিক্রিয়াগুলি ত্রিগুণে কমিয়ে দেওয়া)।
অ্যাডাম কাটজ

আপনি যদি টিটিটি ব্যবহার করতে চলেছেন তবে ttyকমান্ডটি ব্যবহার করবেন না কেন ? যদি আমি কিছু অনুপস্থিত না করি - তবে আমার ধারণা যে এটি সম্ভব?
Pryftan

14

সম্ভবত আপনি যা চান ঠিক তা নয় ... তবে সম্ভবত এসএসএসের মাধ্যমে খোলা পাইপের মাধ্যমে একটি টারবাল পাঠানোর কথা বিবেচনা করুন?

আপনি যে বললেন:

আমাকে হোস্টে ফাইল সঞ্চয় করার অনুমতি নেই।

দীর্ঘমেয়াদে ফাইলগুলি সংরক্ষণের জন্য আপনার কাছে লিখনযোগ্য হোম ডিরেক্টরি বা অন্য সুবিধাজনক অবস্থান না থাকা সম্ভব, তবে আমি বলব যে আপনার পক্ষে কোনও লেখার উপযুক্ত অবস্থান নেই, এমনকি যদি একটি অস্থায়ী tmpfsযা কেবল আপনার জন্য উপলব্ধ করা হবে if বিশেষ সংযোগ

অনেক প্রোগ্রাম (এবং এমনকি libc রুটিন) একটি লিখনযোগ্য প্রয়োজন /tmp, সুতরাং এটি সম্ভবত আপনার জন্য উপলব্ধ হবে।

তারপরে আপনি এমন একটি স্ক্রিপ্ট ব্যবহার করতে পারেন যা টার্বলকে একটি অস্থায়ী ডিরেক্টরিতে আনপ্যাক করে, এসএসএস সংযোগের মাধ্যমে আপনার প্রোগ্রামটি এবং ক্লিনআপ চালায়।

কিছুটা এইরকম:

$ tar cf - file1.txt file2.txt |
  ssh host.name '
      set -e
      tmpdir=$(mktemp -d -t tmp.XXXXXXXXXX)
      cleanup () { rm -rf "$tmpdir"; }
      trap cleanup EXIT
      cd "$tmpdir"
      tar xf -
      /path/to/program -a file1.txt -b file2.txt
  '

ফাইল পাথগুলির সাথে এটির জন্য কিছু বাড়তি যত্নের প্রয়োজন হতে পারে এবং কিছু কর্নার কেস বিবেচনা করার জন্য রয়েছে (তাদের জন্য পরীক্ষা), তবে সাধারণ পদ্ধতির কাজ করা উচিত।

যদি কোনও লিখনযোগ্য ডিরেক্টরি উপলব্ধ না হয় তবে একটি সম্ভাব্য পদ্ধতির মধ্যে programএকটি টারবালকে একক ইনপুট হিসাবে গ্রহণ করতে হবে এবং এর সামগ্রীগুলি মেমোরিতে আনপ্যাক করা হবে। উদাহরণস্বরূপ, যদি programপাইথন স্ক্রিপ্ট হয় তবে অন্তর্নির্মিত tarfileমডিউলটি ব্যবহার করা সহজেই এরকম কিছু সম্পাদন করতে পারে।


3
এমনকি এটিকে ট্র্যাবলিংয়ের ঝামেলা না করেও - আমি কেবলমাত্র কোনও ফাইল লিখতে /tmp/এবং সরাসরি ব্যবহার করার সিদ্ধান্ত নিয়েছি ।
সবুজ পোশাক পরা গাই

2
টারবাল পদ্ধতির কিছু সুবিধা রয়েছে কারণ আপনি একটি একক সংযোগ সংযোগ ব্যবহার করেন (সাফল্য / ব্যর্থতার জন্য পরীক্ষা করার প্রয়োজন নেই) এবং একাধিক একযোগে রানগুলি একে অপরের সাথে চালিত হওয়ার সম্ভাবনা নেই (পৃথক রানের জন্য / টেম্পে ফাইলগুলি ব্যবহার এবং / অথবা মুছুন) ।) তবে আমি মনে করি যে এটি বর্তমানে বিদ্যমান হিসাবে আপনি এসএসএস থেকে সেরা। শুভকামনা!
ফিলাব্রেন্ডেন

3
@ গ্রীনক্লোকগুই তাই সর্বোপরি, আপনি সার্ভারে ঠিকঠাক ফাইল সংরক্ষণ করতে পারেন । অনুগ্রহ করে সেই অনুসারে প্রশ্নটি সংশোধন করুন।
মশবি

1
@mosvy করতে পারেন , হ্যাঁ, কিন্তু করতে চাই না । প্রশ্নটি দাঁড়ায়, একটি "কোনও ফাইল কোনও ফাইল সংরক্ষণ না করেই এটি করা সম্ভব", যার উত্তরটি সম্ভবত "সম্ভবত তবে আমার ক্ষেত্রে তা নয়" বলে মনে হয়
গ্রিন ক্লোক গাই

5

আপনি যদি কোনও টিসিপি শ্রোতা সেট করতে পারেন (একটি উচ্চতর বন্দর হতে পারে), তবে আপনি দ্বিতীয় ইনপুট উত্সটি স্থাপন করতে দ্বিতীয় এসএসএইচ সেশনটি ব্যবহার করতে পারেন nc

উদাহরণ:

সার্ভারে এই স্ক্রিপ্ট রয়েছে ( ~/script.bash):

#!/usr/bin/env bash
cat "$1" | tr a 1
nc localhost "$2" | tr '[:lower:]' '[:upper:]'

এবং স্থানীয়ভাবে এই দুটি ফাইল রয়েছে:

$ cat a 
aaa
aaa
aaa
$ cat b
bbb
bbb
bbb

এখন প্রথমে দ্বিতীয় উত্সটি ( $servসার্ভারটি) শুরু করুন:

ssh "$serv" nc -l -p 2222 -q1 <b &

এবং কমান্ডটি যথাযথভাবে চালান:

$ ssh "$serv" ./script.bash - 2222 <a
111
111
111
BBB
BBB
BBB
[1]+  Done                    ssh "$serv" nc -l -p 2222 -q1 < b

2

এটা একটা স্থাপিত হয় মন্তব্য করে /tmpলিখনযোগ্য, তাই কেবল ফাইল আগে থেকেই এক সময় অনুলিপি:

scp -p file2.txt host.name:/tmp/
ssh host.name "/path/to/program -a /dev/stdin -b /tmp/file2.txt && rm /tmp/file2.txt" < file1.txt

এই কপি ফাইলের পর একটি সফল রান (পরিবর্তন আপ সাফ করে &&একটি থেকে ;আপনি সাফল্যের নির্বিশেষে এটি অপসারণ করতে চান, কিন্তু তারপর মনে রাখবেন আপনি প্রস্থান মান হারাবেন)।


যদি তা গ্রহণযোগ্য না হয় তবে আমি তার সাথে টিঙ্কারিং /path/to/programবা তার জন্য একটি মোড়কের প্রস্তাব দেব যা দুটি ফাইলকে একটি একক ইনপুট স্ট্রিম থেকে আলাদা করতে পারে যেমন:

awk 'FNR == 1 && NR > 1 { printf "%c%c%c", 28, 28, 28 } 1' file1.txt file2.txt \
  | ssh host.name /path/to/tweaked_program

এটি ASCII ইনফরমেশন বিভাজক চারটি (ফাইল বিভাজক, এফএস) ব্যবহার করে এবং এটি তিনগুণ হয়েছে যাতে আমরা যুক্ত হয়ে বাইনারি ফাইলের সম্ভাবনাটি কমানোর সাথে সেই স্ট্রিংটি ধারণ করি। আপনার tweaked_programতখন বিভাজক প্রদত্ত ইনপুটটি বিভক্ত করবে এবং তারপরে দুটি ভেরিয়েবল হিসাবে সংরক্ষণ করা ফাইলগুলিতে কাজ করবে।

অবশ্যই, আপনি যদি টার্বলগুলি মোকাবেলা করার জন্য লাইব্রেরি রয়েছে এমন কোনও ভাষা ব্যবহার করেন, তবে নিরাপদ এবং ক্লিনার পদ্ধতির মধ্যে কেবল এই tarজাতীয় কোডটিতে পাইপ দেওয়া হবে ssh:

tar -zpc file1.txt file2.txt |ssh host.name /path/to/tweaked_program

এবং আপনার সংরক্ষণ tweaked_programকরতে হবে এবং সংরক্ষণাগারটি সঙ্কুচিত করা হবে, প্রতিটি ফাইলকে একটি ভিন্ন ভেরিয়েবলে সংরক্ষণ করুন এবং তারপরে ভেরিয়েবলগুলিতে মূল programলজিকটি চালান ।


1

যদি আপনাকে বন্দরগুলি উপরে ফরোয়ার্ড করার অনুমতি দেওয়া হয় sshএবং আপনার wgetদূরবর্তী মেশিনে এবং busyboxস্থানীয় মেশিনে অ্যাক্সেস থাকে তবে আপনি এর মতো কিছু করতে পারেন:

mkdir /tmp/test; cd /tmp/test
echo 1st_file > 1st_file
echo 2nd_file > 2nd_file

busybox httpd -f -p 127.0.0.1:11080 &
ssh USER@HOST -R 10080:127.0.0.1:11080 '
        cat <(wget -q -O- http://localhost:10080/1st_file) \
            <(wget -q -O- http://localhost:10080/2nd_file)
'
kill $!

( catউদাহরণস্বরূপ প্রোগ্রাম হিসাবে দুটি ফাইল আর্গুমেন্ট গ্রহণ করে)

কেবল পোর্টের মাধ্যমে পোর্ট ফরওয়ার্ড করার ক্ষমতা -Rপ্রয়োজনীয় - HTTP না করে আপনি অন্যান্য পদ্ধতি ব্যবহার করতে পারেন, যেমন। যদি আপনার বিকল্পগুলি এবং বিকল্পগুলি netcatসমর্থন করে :-d-N

nc -Nl localhost 11001 < 1st_file &
nc -Nl localhost 11002 < 2nd_file &
ssh USER@HOST -R 10001:localhost:11001 -R 10002:localhost:11002 '
        cat <(nc -d localhost 10001) <(nc -d localhost 10002)

<(...)দূরবর্তী মেশিনে লগইন শেলটি যদি ksh- বা বাশ-মত না হয় তবে প্রক্রিয়াটির বিকল্পগুলি প্রতিস্থাপনের বিভিন্ন উপায় থাকতে পারে ।

সর্বোপরি, এটি খুব দুর্দান্ত নয় - সঠিক সিস্টেম / শেলস / কনফিগারেশন / অনুমতিগুলি (যা আপনি সরবরাহ করেন নি) সম্পর্কে আরও ভাল জ্ঞান বুদ্ধিমান সমাধানের জন্য অনুমতি দিতে পারে।


-1

আপডেট: এটি সত্যিই কাজ করে না, এসডিএস স্ট্যান্ডিন এবং স্টাডআউট / স্টার্ডার বলতে কী বোঝায় তার খুব সেট ধারণা রয়েছে এবং সত্যিকার অর্থে স্টোরার এটি থেকে পড়তে দেয় না। আমি এই উত্তরটি কাজ না করায় কিছুদিনের মধ্যে মুছে ফেলব। খুব আকর্ষণীয় আলোচনার জন্য ধন্যবাদ !!!


দুর্ভাগ্যবশত এই সরাসরি করতে, যেহেতু একটি দুর্দান্ত উপায় নেই sshক্লায়েন্ট মাত্র তিন ফাইল বর্ণনাকারী পাস হবে ( stdin, stdoutএবং stderrসার্ভারে) এবং অতিরিক্ত ফাইল বর্ণনাকারী (যা এই নির্দিষ্ট ব্যবহারের ক্ষেত্রে জন্য সহায়ক হবে পাস বিধান নেই ।)

(এছাড়াও লক্ষ করুন যে এসএসএইচ প্রোটোকলটিতে অতিরিক্ত ফাইল বর্ণনকারী পাস করার বিধান রয়েছে, কেবল sshক্লায়েন্ট সেই বৈশিষ্ট্যটি ব্যবহার করার কোনও উপায় বাস্তবায়ন করেন না The তাত্ত্বিকভাবে, প্যাচ দিয়ে ক্লায়েন্টকে বাড়ানো এই বৈশিষ্ট্যটি প্রকাশ করার জন্য যথেষ্ট))

আপনি যা সন্ধান করছেন তা সম্পাদনের একটি হ্যাকি উপায় হ'লstderr দ্বিতীয় ফাইলটি পাস করার জন্য ফাইল ডেস্ক্রিপ্টর 2 ( ফাইল বর্ণনাকারী) ব্যবহার করা। কিছুটা এইরকম:

$ ssh remote.name \
      /path/to/program -a /dev/stdin -b /dev/stderr \
      <file1.txt 2<file2.txt

এটি কাজ করা উচিত, যদি programস্ট্যাডারকে লেখার চেষ্টা করে তবে এটি সমস্যার কারণ হতে পারে । আপনি প্রোগ্রাম চালানোর আগে দূরবর্তী প্রান্তে ফাইল বর্ণনাকারীদের পুনরায় জাগল করে আপনি এটিকে ঘিরে কাজ করতে পারেন। আপনি file2.txtবর্ণনাকারী 3 ফাইল এ স্থানান্তর করতে পারেন এবং স্ট্যাডারকে মিরর পুনরায় খুলতে পারবেন:

$ ssh remote.name \
      /path/to/program -a /dev/stdin -b /dev/fd/3 \
      '3<&2' '2>&1' \
      <file1.txt 2<file2.txt

আমি সত্যিই এটি পরীক্ষা করেছি না (কোনও ফোনে টাইপ করা) তবে তাত্ত্বিকভাবে কমপক্ষে আমি এটি কাজ করার আশা করছিলাম। যদি কোনও কারণে তা না হয় তবে আমাকে জানান। চিয়ার্স!
ফিলাব্রেন্ডেন

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

রিমোট কমান্ডে এমসভি, এফডি 0, 1 এবং 2 টি 3 টি ভিন্ন পাইপ হবে। এসএসএস সংযোগে মাল্টিপ্লেক্সেড 3 টি বিভিন্ন চ্যানেলের মাধ্যমে ডেটা ভ্রমণ করে তবে এগুলি এক-দিকনির্দেশক (ক্লায়েন্ট থেকে এফডি 0 এর জন্য বিচ্ছিন্ন এবং সার্ভার থেকে ক্লায়েন্ট 1 এবং 2 এর জন্য), তাই এমনকি পাইপগুলিকে দ্বিদল্শযুক্ত এমন সিস্টেমেও জয়ী হয়েছে '' টি কাজ। লিনাক্সে, কেবলমাত্র পঠন মোডে খোলা / ডেভ / স্টডার পাইপের অন্য প্রান্তে দেয়, তাই এটি কখনই কাজ করবে না।
স্টাফেন চেজেলাস

নোট করুন যে শেষটি রিমোট.নেমে ব্যবহারকারীর লগইন শেলটি বোর্নের মতো ( 3<&2বোর্ন শেল অপারেটর, এবং ক্লায়েন্টের পাঠানো কমান্ডটি ব্যাখ্যা করতে sshd ব্যবহারকারীর লগইন শেলটি চালায়)
স্টাফেন চাজেলাস

2
@ স্টাফেনচাজেলাস নোপ, স্ট্যান্ডিন / স্টাডাউট / স্ট্ডারারের জন্য একটি একক ssh চ্যানেল ব্যবহৃত হয় এবং স্টার্ডার ডেটা SSH_MSG_CHANNEL_EXTENDED_DATAসেট করে টাইপের বার্তাগুলির মাধ্যমে স্থানান্তরিত হয় SSH_EXTENDED_DATA_STDERR। আপনি এখানে
মস্কি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.