বাশ: ইন্টারেক্টিভ রিমোট প্রম্পট


16

আমার কাছে একটি স্ক্রিপ্ট রয়েছে যা দূরবর্তী সার্ভারের সাথে সংযোগ স্থাপন করে এবং কিছু প্যাকেজ ইনস্টল করা আছে কিনা তা পরীক্ষা করে দেখুন:

ssh root@server 'bash -s' < myscript.sh

myscript.sh:

OUT=`rpm -qa | grep ntpdate`
if [ "$OUT" != "" ] ; then
    echo "ntpdate already installed"
else
    yum install $1
fi

এই উদাহরণটি সহজ করা যেতে পারে। এখানে myscript2.shযা একই সমস্যা:

read -p "Package is not installed. Do you want to install it (y/n)?" choise

আমার সমস্যাটি হচ্ছে বাশ আমার উত্তরগুলি ইন্টারেক্টিভভাবে পড়তে পারে না।

ব্যবহারকারীকে প্রম্পট করার ক্ষমতা না হারিয়ে স্থানীয় স্ক্রিপ্ট দূরবর্তীভাবে কার্যকর করার কোনও উপায় আছে কি?


তুমি কি বিস্তারিত বলতে পারো? আপনি কী জিজ্ঞাসা করছেন এটি সত্যই পরিষ্কার নয়? আপনার কোডের আরও কিছু সহায়ক হবে।
slm

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

1
: কিছু প্রয়োজনীয় এই সংক্রান্ত রিসোর্স backreference.org/2011/08/10/...
SLM

উত্তর:


22

এরকম কিছু চেষ্টা করুন:

$ ssh -t yourserver "$(<your_script)"

-tবাহিনীর TTY বরাদ্দ, $(<your_script)পুরো ফাইল সার্চ করতে এবং এই ক্ষেত্রে এক আর্গুমেন্ট হিসাবে বিষয়বস্তু পাসের ssh, যা দূরবর্তী ব্যবহারকারীর শেল দ্বারা নিষ্পন্ন করা হবে।

স্ক্রিপ্টের যদি প্যারামিটারগুলির প্রয়োজন হয় তবে স্ক্রিপ্টের পরে এগুলি পাস করুন:

$ ssh -t yourserver "$(<your_script)" arg1 arg2 ...

আমার পক্ষে কাজ করে, নিশ্চিত না যে এটি সর্বজনীন কিনা।


3
আমি ঠিক তাই খুঁজছিলাম, আপনাকে ধন্যবাদ!
অ্যান্টনি অননিখ

উত্তম সমাধান, তবে your scriptআপনি নিজের উত্তরে যে সিনট্যাক্সটি ব্যবহার করেছেন তার সুবিধাগুলি বজায় রেখে কোনও যুক্তি দেওয়ার কোনও উপায় আছে কি? ssh -t yourserver "$(<your_script --some_arg)"স্রেফ ফলাফল ব্যবহার করে bash: --some_arg: command not found
সাম্পাব্লুকুপার

1
@ সাম্পাব্লুকপার: চেষ্টা করুনssh ... $(<script) script_arg1 script_arg2 ...
ম্যাট

@ ম্যাট, থ্যাঙ্কস, ডাব্লুএফএম :) সম্ভবত এটি আপনার উত্তরটির শৃঙ্খলে যুক্ত করুন?
সাম্পাব্লুকুপার

3

আপনার সমস্যাটি হ'ল sshদূরবর্তী মেশিনে লগইন, অ-ইন্টারেক্টিভ শেল। স্পষ্ট সহজ সমাধান হ'ল স্ক্রিপ্টটি রিমোট সার্ভারে অনুলিপি করা এবং সেখান থেকে চালানো:

scp myscript.sh root@server:/tmp && ssh root@server /tmp/myscript.sh

যদি কোনও কারণেই অনুলিপি করা না হয় তবে আমি স্ক্রিপ্টটি সংশোধন করে প্রথমে সংযোগ স্থাপন করব এবং $1এটি ইনস্টল করা আছে কিনা তা যাচাই করে নেব , তারপরে পুনরায় সংযোগ স্থাপন করুন এবং প্রয়োজনীয় হিসাবে ইনস্টল করুন:

OUT=$(ssh root@server rpm -qa | grep "$1");
if [ "$OUT" != "" ] ; then
    echo "$1 already installed"
else
   read -p "Package $1 is not installed. Do you want to install it (y/n)?" choice
   if [ "$choice" -eq "y" ]; then
       ssh root@server yum install "$1"
   fi
fi

এটাই আমার ভয় ছিল। Ssh এর সাথে সংযোগটি দীর্ঘতম অপারেশন এবং আমি এড়াতে চেষ্টা করছিলাম।
অ্যান্টনি অননিখ

@ অ্যান্থনিঅ্যানিচ আপনি মাস্টার সংযোগ স্থাপনের মাধ্যমে সংযোগ স্থাপনের সময় বাঁচাতে পারেন ।
গিলস 'এস-অশুভ হওয়া বন্ধ করুন'

@ গিলিস আমি এটি প্রস্তাব দেওয়ার কথা ভাবছিলাম কিন্তু আমি ভেবেছিলাম এটি আমার পরামর্শ নিয়ে কাজ করবে না। যদি 1 ম এসএস সংযোগগুলি মাস্টার হিসাবে কাজ করে তবে এটি $OUT=$(ssh root@server rpm -qa | grep "$1");প্রস্থানের পরে বন্ধ হয়ে যাবে এবং দ্বিতীয় তৃতীয় সংযোগটি প্রথমটির মতো সময় নিবে। আমি কি ভূল?
টেরডন

1
@terdon মাস্টার হিসাবে ssh -M foo.example.com sleep 99999999বা এর ssh -M foo.example.com read <somefifoমতো কিছু চালান এবং আপনার কাজ শেষ হয়ে গেলে এটি স্পষ্টভাবে ( killবা সাথে echo done >somefifo) হত্যা করুন ।
গিলস 'এস-অশুভ হওয়া বন্ধ করুন'

0

এখানে একটি ভাল ব্যাখ্যা

তাই আমি স্ক্রিপ্টটি মানিয়ে নিয়েছি

hostname
echo -n "Make your choice :"
read choice
echo "You typed " ${choice}
echo done

এবং এটি কার্যকর হয়নি।

সুতরাং আমি স্ক্রিপ্টকে স্থানীয় রিডাইরেকশন এড়ানোর জন্য রিমোটে স্থানান্তরিত করেছি। (আমার কমান্ডগুলি এফ নামের একটি ফাইলে রয়েছে )

cat f | ssh user@remotehost.com 'cat >remf'
ssh user@remotehost bash remf

এটি কাজ করে। এখানে ফলাফল:

christian@clafujiu:~/tmp$ ssh localhost bash tmp/f
christian@localhost's password: 
Linux clafujiu 2.6.32-52-generic #114-Ubuntu SMP Wed Sep 11 19:00:15 UTC 2013 i686 GNU/Linux
Sun Nov 10 14:58:56 GMT 2013
Make your choice :abc
You typed  abc
done

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

REMID=`cat f |ssh user@remotehost 'cat > remf_$$; echo $$'` ;ssh root@redtoadservices.com "bash remf_${REMID} ; rm -v remf_${REMID}"

2
কিভাবে এটি "কাজ"? আপনি কি bash -s < script.shওপি'র মতো এই স্ক্রিপ্টটি চালিয়েছেন? আপনি কি উত্তরটি যুক্ত করার পরিবর্তে আপনার উত্তরটিতে ব্যাখ্যাটি অন্তর্ভুক্ত করতে পারেন?
টেরডন

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

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

0

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

সম্প্রতি আমি মুখোমুখি হয়েছি যে কমান্ড লাইন বাফার আকারটি সাধারণত বেশ বড় হয় ('getconf ARG_MAX> 2MB আমি যেখানে দেখেছি)'। এবং এটি কীভাবে আমি এটি ব্যবহার করতে পারি এবং পালানোর সমস্যাটি প্রশমিত করতে পারি তার সম্পর্কে আমাকে ভাবতে বাধ্য করল।

ফলাফল হলো:

ssh -t <host> /bin/bash "<(echo "$(cat my_script | base64 | tr -d '\n')" | base64 --decode)" <arg1> ...

বা এখানে একটি নথি এবং বিড়াল ব্যবহার:

ssh -t <host> /bin/bash $'<(cat<<_ | base64 --decode\n'$(cat my_script | base64)$'\n_\n)' <arg1> ...

আমি এই ধারণাটি পুরোপুরি কার্যকর BASH উদাহরণ স্ক্রিপ্ট উত্পাদন করতে প্রসারিত করেছি sshxযা স্বেচ্ছাসেবী স্ক্রিপ্টগুলি চালাতে পারে (কেবল BASH নয়), যেখানে আর্গুমেন্টগুলি স্থানীয় ইনপুট ফাইলগুলিও হতে পারে এসএসএসের মাধ্যমে। এখানে দেখুন ।


আকর্ষণীয়, তবে কীভাবে এবং / বা কখন ম্যাট এর উত্তরের চেয়ে ভাল ?
স্কট

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

(1) আপনি কি এমন কোনও স্ক্রিপ্টের এমসিভিই পোস্ট করতে পারেন যার জন্য মাদুর উত্তরটি ব্যর্থ হয় (এবং আপনার কাজ করে)? (২) দেখুন “প্রতিধ্বনি $ (স্টাফ)” বা “প্রতিধ্বনি` স্টাফ ”এর মধ্যে কী ভুল?  আপনার echo "$(cat my_script | base64)" | base64 --decodeচেহারা সমান (-শ) cat my_script | base64 | base64 --decode, যা দেখতে অনেকটা কোনও অপ-অপেশনের মতো।
স্কট

হাই @ স্কট (1): স্ক্রিপ্ট বিবেচনা করুন: echo "ARG1=$1, USER=$USER, END"। a) $ ssh host "$(<my_bash)" foo-> ARG1=, USER=user, END foo। খ) $ ssh host bash "<(echo $(cat my_bash|base64) | base64 --decode)" foo-> ARG1=foo, USER=user, END। এখানে (ক) কার্যকরভাবে চলছে: bash -c $'#!/bin/bash\necho "ARG1=$1, USER=$USER, END" foo'বা অনুরূপ কিছু। নোট করুন আরগটি কাজ করে না। কোথায় (খ) চলমান: bash <(echo IyEvY...5EIgo= | base64 --decode) foo। (2) পরিবহন এনকোডিং হিসাবে আমি বেস 64 ব্যবহার করেছি।
সোর্সসিমিয়ান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.