সিউডো-টার্মিনাল বরাদ্দ দেওয়া হবে না কারণ স্টিডিন কোনও টার্মিনাল নয়


345

আমি একটি শেল স্ক্রিপ্ট লেখার চেষ্টা করছি যা দূরবর্তী সার্ভারে কিছু ডিরেক্টরি তৈরি করে এবং তারপরে আমার স্থানীয় মেশিন থেকে রিমোটে ফাইলগুলি অনুলিপি করতে scp ব্যবহার করে। আমার এখন পর্যন্ত যা আছে তা এখানে:

ssh -t user@server<<EOT
DEP_ROOT='/home/matthewr/releases'
datestamp=$(date +%Y%m%d%H%M%S)
REL_DIR=$DEP_ROOT"/"$datestamp
if [ ! -d "$DEP_ROOT" ]; then
    echo "creating the root directory"
    mkdir $DEP_ROOT
fi
mkdir $REL_DIR
exit
EOT

scp ./dir1 user@server:$REL_DIR
scp ./dir2 user@server:$REL_DIR

আমি যখনই এটি চালাব আমি এই বার্তাটি পাই:

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

এবং স্ক্রিপ্টটি চিরকাল স্থায়ী।

আমার সার্বজনীন কী সার্ভারে বিশ্বাসী এবং আমি স্ক্রিপ্টের বাইরে সমস্ত কমান্ড চালাতে পারি। কোন ধারনা?


4
আপনি সহজেই টার্মিনালটি নির্দিষ্ট করতে পারেন যেমনssh user@server /bin/bash <<EOT…
বুজুত

3
@ বুজুত: আপনি সম্ভবত শেল বোঝাচ্ছেন , তবে, হ্যাঁ, /bin/bashসমস্যাটি এড়ানোর এক উপায় স্পষ্টভাবে উল্লেখ করা ।
mklement0

1
@ এমকিলেটমেন্ট 0 আসলে, আমি এটাই বোঝাতে চাইছি। এটি সংশোধন করার জন্য Thx;)
বুজুত

উত্তর:


512

স্টিডিন টার্মিনাল না হলেও সিউডো-টিটি বরাদ্দকে বাধ্য করার জন্য ssh -t -t(বা ssh -ttসংক্ষেপে) চেষ্টা করুন ।

আরও দেখুন: বাশ স্ক্রিপ্ট দ্বারা সম্পাদিত এসএসএইচ অধিবেশন শেষ হচ্ছে

Ssh ম্যানপেজ থেকে:

-T      Disable pseudo-tty allocation.

-t      Force pseudo-tty allocation.  This can be used to execute arbitrary 
        screen-based programs on a remote machine, which can be very useful,
        e.g. when implementing menu services.  Multiple -t options force tty
        allocation, even if ssh has no local tty.

21
এখানে চালিত স্ক্রিপ্টে আমার একই রকম সমস্যা রয়েছে। আমি টি-টি যোগ করেছি তবে এখন আমি একটি নতুন ত্রুটি পাচ্ছি। "tcgetattr: ডিভাইসের জন্য অনুপযুক্ত ioctl"
মাস্টারজেড

5
কেন ssh -t -tএবং না ssh -tt? এমন কোনও পার্থক্য আছে যা সম্পর্কে আমি অবগত নই?
জ্যাক

3
@ মাস্টারজেড একই জিনিস এখানে। এটির উত্তর পেয়ে ভাল Inappropriate IOCtl for device
লাগবে

11
@ জ্যাক -ttএবং -t -tসমতুল্য; আরোগুলি পৃথকভাবে নির্দিষ্ট করা বা একসাথে স্মুশ করা ব্যক্তিগত শৈলী / পছন্দ হিসাবে বিবেচিত হয়ে যায় এবং এটি যখন নেমে আসে তখন এটি কোনওভাবেই করার জন্য বৈধ যুক্তি রয়েছে are তবে সত্যই, এটি কেবল ব্যক্তিগত পছন্দ।
জেডিএস

5
"Ssh এর কোনও স্থানীয় tty না থাকলেও" এর অর্থ কী?
সিএমসিডিগ্রাগনকাই

192

ম্যানুয়াল-T থেকে বিকল্প সহ

সিউডো-টিটি বরাদ্দ অক্ষম করুন


11
এই উত্তরটির আরও পয়েন্ট দরকার - এটি সঠিক উত্তর, এবং জ্যাঙ্কোর উত্তরের মতো খুব দীর্ঘ নয়, এটি অবাস্তব যে "ওহ যে কোনওভাবেই -T -t দিয়ে একটি টিটিওয়াই বরাদ্দ করুন" 107 পয়েন্ট পায়, যখন আপনি কেবল এটি পুরোপুরি এড়িয়ে যেতে পারেন
নেহদ

2
শুধু upvated; এটি আমার পক্ষে
-টি-টি-টি-র

15
'-টি-টি' কাজ করে, তবে '-টি' আমি 'সুডো'র সাথে: দুঃখিত, সুডো চালানোর জন্য আপনার অবশ্যই একটি টিটি থাকতে হবে'
ইভান বালাশভ

3
@ নেহেদ: -ttআমাদের মধ্যে যারা টিটিওয়াই প্রকৃতপক্ষে চায় এবং বিকল্পধারার ত্রুটির বার্তাটি পাচ্ছে তাদের জন্য বিকল্পটি সর্বোত্তম প্রদর্শিত হবে। -Tআপনার টিটিওয়াইয়ের প্রয়োজন না থাকলে এই উত্তরটি আরও ভাল।
এরিচবিএসচুল্জ

3
@ নেড - নিশ্চিত - তবে আমি নিশ্চিত যে আমার মতো অন্যরাও গুগলিং থেকে ত্রুটি বার্তায় ত্রুটিটি এখানে পেয়েছিল। প্রতিযোগিতামূলক উত্তরের মধ্যে অন্যান্য গুগলরা কীভাবে বেছে নেবেন তা পরিষ্কার করা অযৌক্তিক বলে মনে হয় না। হয়তো বা না. আমি জানি না
এরিকবিএসচুল্জ

91

প্রতি zanco এর উত্তর , আপনি একটি দূরবর্তী কমান্ড প্রদান করছি না sshদেওয়া কিভাবে শেল কমান্ড লাইন parses। এই সমস্যাটি সমাধান করার জন্য, আপনার sshকমান্ডের অনুরোধের সিনট্যাক্সটি পরিবর্তন করুন যাতে রিমোট কমান্ডটি সিনট্যাকটিক্যালি সঠিক, মাল্টি-লাইনের স্ট্রিং নিয়ে গঠিত।

বিভিন্ন সিনট্যাক্স ব্যবহার করা যেতে পারে। উদাহরণস্বরূপ, যেহেতু কমান্ডগুলি পাইপ করা যায় bashএবং shএবং সম্ভবত অন্যান্য শাঁসগুলিও, তাই সহজ সমাধান হ'ল sshহেরোডোকসের সাথে শেল ডাকে একত্রিত করা :

ssh user@server /bin/bash <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT

মনে রাখবেন যে উপরেরটি বাদ দিয়ে কার্যকর করা /bin/bashসতর্কবার্তা হিসাবে দেখা দেয় Pseudo-terminal will not be allocated because stdin is not a terminal। এছাড়াও নোট করুন যে EOTএকক-কোট দ্বারা বেষ্টিত, যাতে হেরেডোককেbash একটি নওডোক হিসাবে স্বীকৃতি দেয় , স্থানীয় ভেরিয়েবল ইন্টারপোলেশনটি বন্ধ করে দেয় যাতে কমান্ড পাঠ্যটি যেমন পাঠানো হয় তেমন পাস হবে ssh

আপনি যদি পাইপগুলির অনুরাগী হন তবে আপনি উপরের মতো নীচে আবার লিখতে পারেন:

cat <<'EOT' | ssh user@server /bin/bash
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT

/bin/bashউপরের ক্ষেত্রে একই ক্যাভিয়েট প্রযোজ্য।

bashভেরিয়েবল ইন্টারপোলেশনের একাধিক স্তর নিম্নরূপ ব্যবহার করে একটি একক স্ট্রিং হিসাবে মাল্টি-লাইন রিমোট কমান্ডটি পাস করার জন্য আরেকটি বৈধ পন্থা :

ssh user@server "$( cat <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
)"

উপরের সমাধানটি নিম্নলিখিত পদ্ধতিতে এই সমস্যাটি সমাধান করে:

  1. ssh user@serverব্যাশ দ্বারা পার্স করা হয়, এবং হতে ব্যাখ্যা করা হয় sshকমান্ড একটি আর্গুমেন্ট দ্বারা অনুসরণ user@serverপ্রেরণ করা sshকমান্ড

  2. "একটি বিভক্ত স্ট্রিং শুরু হয়, যা শেষ হয়ে গেলে, sshকমান্ডে প্রেরণের জন্য একটি যুক্তি তৈরি করবে , যা এই ক্ষেত্রে sshকার্যকর করতে দূরবর্তী কমান্ড দ্বারা ব্যাখ্যা করা হবেuser@server

  3. $( আউটপুটটি পার্শ্ববর্তী ইন্টারপোল্টেড স্ট্রিং দ্বারা ক্যাপচার করার সাথে সাথে একটি কমান্ড কার্যকর করা শুরু করে

  4. catযা কিছু ফাইল অনুসরণ করে তার সামগ্রীর আউটপুট দেওয়ার একটি কমান্ড। এর আউটপুট catক্যাপচারিং ইন্টারপোলটেড স্ট্রিংয়ে ফিরে আসবে

  5. <<একটি বাশ হেরডোক শুরু

  6. 'EOT'নির্দিষ্ট করে যে বংশের নাম EOT OT ইওটির' আশেপাশের একক উদ্ধৃতি উল্লেখ করে যে হেরডোককে একটি নওডোক হিসাবে পার্স করা উচিত , যা হেরডোকের একটি বিশেষ রূপ যেখানে বিষয়বস্তুগুলি ব্যাশ দ্বারা বিভক্ত হয় না, বরং আক্ষরিক বিন্যাসে চলে যায়

  7. যেকোনো সামগ্রীকে মধ্যে সম্মুখীন হয় <<'EOT'এবং <newline>EOT<newline>nowdoc আউটপুট যোগ করা হবে

  8. EOTনোডককে সমাপ্ত করে, ফলস্বরূপ একটি নোডক অস্থায়ী ফাইল তৈরি হয়েছিল এবং কলিং catকমান্ডে ফিরে যায় । catনাওডক আউটপুট দেয় এবং আউটপুটটিকে ক্যাপচারিং ইন্টারপোলটেড স্ট্রিংয়ে ফেরত দেয়

  9. ) কমান্ড কার্যকর করার জন্য সমাপ্ত

  10. "ক্যাপচারিং ইন্টারপোলটেড স্ট্রিং শেষ করে। ইন্টারপোল্টেড স্ট্রিংয়ের বিষয়বস্তুগুলি sshএকটি একক কমান্ড লাইন আর্গুমেন্ট হিসাবে ফেরত দেওয়া sshহবে , যা কার্যকর করতে দূরবর্তী কমান্ড হিসাবে ব্যাখ্যা করবেuser@server

আপনার যদি বাহ্যিক সরঞ্জামগুলির মতো এড়ানো দরকার catএবং একটার পরিবর্তে দুটি বিবৃতি দেওয়া মনে না হয় readতবে এসএসএইচ কমান্ড জেনারেট করার জন্য হেরডোক সহ বিল্ট-ইনটি ব্যবহার করুন :

IFS='' read -r -d '' SSH_COMMAND <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT

ssh user@server "${SSH_COMMAND}"

+1 দেড় বছর পরে! :) সত্যিই পরিষ্কার ব্যাখ্যা। ভাল হয়েছে
yaroslavTir

1
আমার জন্য (এবং আমি কোনওভাবেই "ডিওঅপস" ব্যক্তি) এটি যা কাজ করেছিল (আমি জেনকিন্স ব্যবহার করছি)। আমি "-t -t" এবং "-T" পরামর্শগুলি চেষ্টা করেও খোলামেলা স্ট্রিম ইস্যু এবং সম্পাদন না করার সমস্যাগুলিতে চলে এসেছি।
রায়ান ক্রু 21

2 বছর পরে, সত্যই সহায়ক
জ্যাক-নি

+1 অসাধারণ ব্যাখ্যা। তবে আপনি যদি শেষ কোড স্নিপেট (আইএফএস = '' *) দূরবর্তী কমান্ডগুলি কার্যকর করার জন্য একটি ফাংশন করেন তবে আপনি কীভাবে FS 1 কে আইএফএস = '' * তে পাস করবেন? মনে হচ্ছে এটি মোটামুটি $ 1 এর সামগ্রীটিকে স্বীকৃতি দেয়।
ক্রিশ্চিয়ান ম্যাথিয়াস আম্বাইক

1
@ এম কেলেটমেন্ট ০ অবশ্যই, আপনি প্রয়োজন মতো স্ট্রিংগুলি থেকে বাঁচতে পারবেন তবে স্ক্রিপ্টের বিবৃতিগুলি যে আপনি কেবল অন্য শেল স্ক্রিপ্ট থেকে অনুলিপি এবং আটকানো হতে পারেন, বা সেই বিষয়ে স্ট্যাকওভারফ্লো প্রবাহিত করার ঝামেলা চায়? এছাড়াও, catসমাধানের কমনীয়তা হ'ল এটি একক (যৌগিক যৌগিক) বিবৃতিতে সম্পন্ন হয় এবং ফলস্বরূপ শেল পরিবেশকে দূষণকারী অস্থায়ী পরিবর্তনগুলির ফলে আসে না।
দেজয় ক্লেটন

63

আমি এই উত্তরটি যুক্ত করছি কারণ এটি একটি একই সমস্যাটির সমাধান করেছে যা আমার একই ত্রুটি বার্তায় ছিল।

সমস্যা : আমি উইন্ডোজ এর অধীনে সাইগউইন ইনস্টল করেছি এবং এই ত্রুটিটি পেয়েছিলাম:Pseudo-terminal will not be allocated because stdin is not a terminal

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


10
আমার জন্য এটি প্রমাণিত হয়েছিল যে এটি $ which ssh/cygdrive/c/Program Files (x86)/Git/bin/ssh
পাঠের

এবং এটি ইনস্টল opensshকরার জন্য উইন্ডোজ যাওয়ার উপায় হতে পারে: superuser.com/a/301026/260710
Andreas Dietrich

এই সমাধানটি আমার পক্ষে কাজ করে। ওপেনশ ইনস্টল করার পরে, সমস্যাটি চলে গেছে।
jdhao

34

সতর্কতা বার্তাটি Pseudo-terminal will not be allocated because stdin is not a terminal.এ কারণে যে এখানে কোনও sshনথি থেকে স্টিডিন পুনঃনির্দেশিত হওয়ার সময় কোনও কমান্ড নির্দিষ্ট করা হয়নি । একটি আর্গুমেন্ট হিসাবে একটি নির্দিষ্ট কমান্ডের অভাবের কারণে sshপ্রথমে একটি ইন্টারেক্টিভ লগইন সেশনটি প্রত্যাশা করে (যার জন্য রিমোট হোস্টের জন্য pty বরাদ্দ প্রয়োজন) তবে তার পরে বুঝতে হবে যে এর স্থানীয় স্টিডিন কোনও tty / pty নয়। sshএখানে দলিল থেকে স্টিডিন পুনঃনির্দেশ করার জন্য একটি কমান্ড (যেমন /bin/sh) এর প্রয়োজন হিসাবে আর্গুমেন্ট হিসাবে নির্দিষ্ট করা দরকার ssh- এবং এই জাতীয় ক্ষেত্রে কোনও pty ডিফল্টরূপে দূরবর্তী হোস্টে বরাদ্দ করা হবে না।

যেহেতু কোন কমান্ড মাধ্যমে মৃত্যুদন্ড কার্যকর করা হবে sshযে (যেমন একটি TTY / Pty উপস্থিতিতে প্রয়োজন vimবা top) -tস্যুইচ করার sshপ্রযোজন নেই। কেবল ব্যবহার করুন ssh -T user@server <<EOT ...বা ssh user@server /bin/bash <<EOT ...সতর্কতাটি চলে যাবে।

যদি <<EOFএড়ানো না যায় বা এখানে নথির অভ্যন্তরে একক-উদ্ধৃত (অর্থাত্ ) <<\EOTবা <<'EOT'ভেরিয়েবলগুলি কার্যকর করা হওয়ার আগে স্থানীয় শেল দ্বারা প্রসারিত করা হবে ssh ...। এর প্রভাবটি হ'ল এখানে নথির অভ্যন্তরের ভেরিয়েবলগুলি খালি থাকবে কারণ এগুলি কেবল দূরবর্তী শেলের মধ্যে সংজ্ঞায়িত করা হয়েছে।

সুতরাং, যদি $REL_DIRস্থানীয় শেল দ্বারা উভয়ই অ্যাক্সেসযোগ্য এবং দূরবর্তী শেলটিতে $REL_DIRসংজ্ঞায়িত হওয়া উচিত তবে sshকমান্ডের আগে এখানে নথির বাইরে সংজ্ঞায়িত করতে হবে ( নীচের সংস্করণ 1 ); অথবা, যদি <<\EOTবা <<'EOT'ব্যবহৃত হয়, তবে sshকমান্ডের আউটপুট নির্ধারিত হতে পারে REL_DIRযদি sshstdout- র কমান্ডের একমাত্র আউটপুট পলায়িত echo "$REL_DIR"/ একক-উদ্ধৃত এখানে নথির ( নীচের সংস্করণ 2 ) ভিতরে তৈরি করা হয়।

তৃতীয় বিকল্পটি হ'ল ডকুমেন্টটি একটি ভেরিয়েবলে সংরক্ষণ করা এবং তারপরে এই ভেরিয়েবলটি একটি কমান্ড আর্গুমেন্ট হিসাবে ssh -t user@server "$heredoc"( নীচে সংস্করণ 3 ) পাস করা ।

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

# version 1

unset DEP_ROOT REL_DIR
DEP_ROOT='/tmp'
datestamp=$(date +%Y%m%d%H%M%S)
REL_DIR="${DEP_ROOT}/${datestamp}"

ssh localhost /bin/bash <<EOF
if [ ! -d "$DEP_ROOT" ] && [ ! -e "$DEP_ROOT" ]; then
   echo "creating the root directory" 1>&2
   mkdir "$DEP_ROOT"
fi
mkdir "$REL_DIR"
#echo "$REL_DIR"
exit
EOF

scp -r ./dir1 user@server:"$REL_DIR"
scp -r ./dir2 user@server:"$REL_DIR"


# version 2

REL_DIR="$(
ssh localhost /bin/bash <<\EOF
DEP_ROOT='/tmp'
datestamp=$(date +%Y%m%d%H%M%S)
REL_DIR="${DEP_ROOT}/${datestamp}"
if [ ! -d "$DEP_ROOT" ] && [ ! -e "$DEP_ROOT" ]; then
   echo "creating the root directory" 1>&2
   mkdir "$DEP_ROOT"
fi
mkdir "$REL_DIR"
echo "$REL_DIR"
exit
EOF
)"

scp -r ./dir1 user@server:"$REL_DIR"
scp -r ./dir2 user@server:"$REL_DIR"


# version 3

heredoc="$(cat <<'EOF'
# -onlcr: prevent the terminal from converting bare line feeds to carriage return/line feed pairs
stty -echo -onlcr
DEP_ROOT='/tmp'
datestamp="$(date +%Y%m%d%H%M%S)"
REL_DIR="${DEP_ROOT}/${datestamp}"
if [ ! -d "$DEP_ROOT" ] && [ ! -e "$DEP_ROOT" ]; then
   echo "creating the root directory" 1>&2
   mkdir "$DEP_ROOT"
fi
mkdir "$REL_DIR"
echo "$REL_DIR"
stty echo onlcr
exit
EOF
)"

REL_DIR="$(ssh -t localhost "$heredoc")"

scp -r ./dir1 user@server:"$REL_DIR"
scp -r ./dir2 user@server:"$REL_DIR"

5
একটি হেরডোক ব্যবহার করার সময় এই ত্রুটিটির অর্থ কী এবং কেন এটি প্রদর্শিত হচ্ছে এর খুব বিশদ ব্যাখ্যার জন্য আপনাকে ধন্যবাদ, এটি আমাকে কেবল এটির চারপাশে কাজ করার পরিবর্তে এটি বুঝতে আসলে সহায়তা করেছিল।
ড্যান

29

সমস্ত প্রাসঙ্গিক তথ্য বিদ্যমান উত্তরের মধ্যে রয়েছে তবে আমাকে একটি বাস্তবিক সংক্ষিপ্তসার চেষ্টা করতে দিন :

TL; ড:

  • কমান্ড-লাইন আর্গুমেন্ট ব্যবহার করে চালানোর জন্য আদেশগুলি পাস করুন :
    ssh jdoe@server '...'

    • '...' স্ট্রিংগুলি একাধিক লাইনের বিস্তৃত হতে পারে, সুতরাং আপনি এখানে কোনও নথির ব্যবহার ছাড়াই আপনার কোডটি পঠনযোগ্য রাখতে পারেন:
      ssh jdoe@server ' ... '
  • কমান্ডগুলি স্টিডিনের মাধ্যমে পাস করবেন না , যেমন আপনি এখানে-নথিটি ব্যবহার করার ক্ষেত্রে করেন :
    ssh jdoe@server <<'EOF' # Do NOT do this ... EOF

কমান্ডগুলি আর্গুমেন্ট হিসাবে পাস করা যেমন রয়েছে তেমন কাজ করে এবং:

  • সিউডো-টার্মিনাল নিয়ে সমস্যাটি ওঠে না।
  • exitআপনার কমান্ডগুলির শেষে আপনার কোনও বিবৃতি প্রয়োজন হবে না , কারণ আদেশগুলি প্রক্রিয়া করার পরে সেশনটি স্বয়ংক্রিয়ভাবে প্রস্থান করবে।

সংক্ষেপে: স্টিডিনের মাধ্যমে কমান্ডগুলি পাস করা এমন একটি প্রক্রিয়া যা sshএর নকশার সাথে দ্বন্দ্বপূর্ণ এবং এর ফলে সমস্যা তৈরি হয় যা পরে কাজ করা উচিত।
আরও জানতে চাইলে পড়ুন।


Backgroundচ্ছিক পটভূমি তথ্য:

sshটার্গেট সার্ভারে কমান্ড গ্রহণের জন্য কমান্ড গ্রহণ করার পদ্ধতিটি একটি কমান্ড-লাইন আর্গুমেন্ট : চূড়ান্ত অপারেন্ড (অ-বিকল্প যুক্তি) এক বা একাধিক শেল কমান্ডযুক্ত একটি স্ট্রিং গ্রহণ করে।

  • ডিফল্টরূপে, এই কমান্ডগুলি অদ্ভুতভাবে চালিত, অ-ইন্টারেক্টিভ শেলের মধ্যে (সিউডো) টার্মিনাল ব্যবহার না করে (বিকল্পটি -Tবোঝানো হয়) এবং শেষ কমান্ডটি প্রক্রিয়া শেষ করার পরে সেশনটি স্বয়ংক্রিয়ভাবে শেষ হয়

  • আপনার কমান্ডগুলির ব্যবহারকারীর ইন্টারঅ্যাকশন প্রয়োজন যেমন ইভেন্টের ক্ষেত্রে যেমন একটি ইন্টারেক্টিভ প্রম্পটের প্রতিক্রিয়া জানান, আপনি স্পষ্টরূপে একটি pty (সিউডো-টিটি) , সিউডো টার্মিনাল তৈরির জন্য অনুরোধ করতে পারেন , যা -tবিকল্পটি ব্যবহার করে দূরবর্তী সেশনের সাথে ইন্টারঅ্যাক্ট করতে সক্ষম হয় ; উদাহরণ:

    • ssh -t jdoe@server 'read -p "Enter something: "; echo "Entered: [$REPLY]"'

    • লক্ষ করুন যে ইন্টারেক্টিভ readপ্রম্পটটি কেবলমাত্র একটি পিটিআইয়ের সাথে সঠিকভাবে কাজ করে, সুতরাং -tবিকল্পটি প্রয়োজন।

    • পিটিআই ব্যবহারের একটি উল্লেখযোগ্য পার্শ্ব প্রতিক্রিয়া রয়েছে: স্টডআউট এবং স্ট্ডার একত্রিত হয় এবং উভয়ই স্টাডাউটের মাধ্যমে রিপোর্ট করা হয় ; অন্য কথায়: আপনি নিয়মিত এবং ত্রুটি আউটপুট মধ্যে পার্থক্য হারাতে; উদাহরণ:

      • ssh jdoe@server 'echo out; echo err >&2' # OK - stdout and stderr separate

      • ssh -t jdoe@server 'echo out; echo err >&2' # !! stdout + stderr -> stdout

এই তর্কের অভাবে, sshএকটি ইন্টারেক্টিভ শেল তৈরি করে - আপনি স্টিডিনের মাধ্যমে কমান্ড প্রেরণ করার সাথে সাথে , যেখানে সমস্যাটি শুরু হয়:

  • একটি ইন্টারেক্টিভ শেলের জন্য, sshসাধারণত স্টাইডিনটি (রিয়েল) টার্মিনালের সাথে সংযুক্ত না থাকে তবে ডিফল্টরূপে একটি পিটিআই (সিউডো-টার্মিনাল) বরাদ্দ করে ।

    • স্ট্ডিনের মাধ্যমে কমান্ড প্রেরণের অর্থ sshহ'ল স্ট্ডিন আর কোনও টার্মিনালের সাথে সংযুক্ত থাকে না, সুতরাং কোনও পিটিআই তৈরি হয় না এবং সেই অনুসারে আপনাকে ssh সতর্ক করে দেয় :
      Pseudo-terminal will not be allocated because stdin is not a terminal.

    • এমনকি -tবিকল্প, যার স্পষ্ট উদ্দেশ্য একটি pty তৈরির অনুরোধ করা এই ক্ষেত্রে যথেষ্ট নয় : আপনি একই সতর্কতা পাবেন।

      • কিছুটা অদ্ভুতভাবে, তাহলে আপনি আবশ্যক দ্বিগুণ-t বিকল্প : একটি Pty বল সৃষ্টি করতে ssh -t -t ...বা ssh -tt ...দেখায় যা আপনি সত্যিই সত্যিই এটা মানে

      • সম্ভবত এই খুব ইচ্ছাকৃত পদক্ষেপের প্রয়োজনীয়তার যুক্তিটি হ'ল জিনিসগুলি প্রত্যাশার মতো কাজ করতে পারে না । উদাহরণস্বরূপ, ম্যাকোস 10.12-এ, উপরের কমান্ডের আপাত সমতুল্য, স্টিডিনের মাধ্যমে কমান্ড সরবরাহ করে এবং ব্যবহার করে -tt, সঠিকভাবে কাজ করে না ; readপ্রম্পটে সাড়া দেওয়ার পরে অধিবেশন আটকে যায় :
        ssh -tt jdoe@server <<<'read -p "Enter something: "; echo "Entered: [$REPLY]"'


আর্গুমেন্ট হিসাবে আপনি যে আদেশগুলি পাস করতে চান সে ক্ষেত্রে আপনার সিস্টেমে কমান্ড লাইনটি অনেক দীর্ঘ করে দেয় (যদি এর দৈর্ঘ্য এগিয়ে আসে getconf ARG_MAX- এই নিবন্ধটি দেখুন ), প্রথমে স্ক্রিপ্ট আকারে কোডটি রিমোট সিস্টেমে অনুলিপি করার বিষয়ে বিবেচনা করুন ( ব্যবহার করে, যেমন, scp) ব্যবহার করুন এবং তারপরে সেই স্ক্রিপ্টটি কার্যকর করতে একটি আদেশ প্রেরণ করুন।

একটি চিম্টিতে, স্টিডিনের-T মাধ্যমে একটি কমান্ড কমান্ড সহ কমান্ডগুলি ব্যবহার করুন এবং সরবরাহ করুন , তবে মনে রাখবেন যে আপনার যদি ইন্টারঅ্যাকটিভ বৈশিষ্ট্যগুলিরও প্রয়োজন হয়, তার পরিবর্তে কাজ নাও করতে পারেন।exit-tt-T


1
এটি নিখুঁতভাবে কাজ করেছে, -এসটি উপায়টি এসএমএসের মাধ্যমে প্রেরিত প্রতিটি কমান্ড টার্মিনাল প্রদর্শন করে।

1
"একটি pty তৈরির জন্য জোর করার জন্য দ্বিগুণ বিকল্প বিকল্প: ssh -t -t ... বা ssh -t ... দেখায় যে আপনি সত্যই, সত্যই এটির অর্থ" " - হা, হা - ধন্যবাদ এটি মজার কিন্তু
গুরুতরও

22

হ্যাংটি কোথা থেকে এসেছে তা আমি জানি না, তবে একটি ইন্টারেক্টিভ এসএসে কমান্ডগুলি পুনর্নির্দেশ করা (সাধারণত) বা সমস্যা সমাধানের একটি রেসিপি। কমান্ড-টু-রান-হিসাবে-সর্বশেষ-আর্গুমেন্ট স্টাইলটি ব্যবহার করা এবং ssh কমান্ড লাইনে স্ক্রিপ্টটি পাস করা আরও দৃ rob়:

ssh user@server 'DEP_ROOT="/home/matthewr/releases"
datestamp=$(date +%Y%m%d%H%M%S)
REL_DIR=$DEP_ROOT"/"$datestamp
if [ ! -d "$DEP_ROOT" ]; then
    echo "creating the root directory"
    mkdir $DEP_ROOT
fi
mkdir $REL_DIR'

(সব কিছু এক দৈত্য- 'প্রশমিত মাল্টলাইন কমান্ড-লাইন আর্গুমেন্টে)।

সিউডো-টার্মিনাল বার্তা হ'ল কারণ -tযা আপনার ssh কে রিমোট মেশিনে চালিত পরিবেশ তৈরি করার চেষ্টা করতে বলে সেখানে চালিত প্রোগ্রামগুলিকে প্রকৃত টার্মিনালের মতো দেখায়। আপনার ssh ক্লায়েন্টটি এটি করতে অস্বীকার করছে কারণ তার নিজস্ব স্ট্যান্ডার্ড ইনপুটটি টার্মিনাল নয়, তাই এর স্থানীয় প্রান্তে দূরবর্তী মেশিন থেকে আপনার আসল টার্মিনালে বিশেষ টার্মিনাল এপিআইগুলি পাশ করার কোনও উপায় নেই।

-tযাইহোক আপনি কী অর্জন করার চেষ্টা করছেন ?


1
-T বিকল্পটি Psuedo টার্মিনাল সমস্যাটি সমাধান করার চেষ্টা ছিল (এটি কাজ করে না)। আমি আপনার সমাধানটি চেষ্টা করেছিলাম, এটি psuedo টার্মিনাল জিনিসটি থেকে মুক্তি পেয়েছে তবে এখন এটি কেবল ঝুলছে ...
ম্যাথু

4
@ হেনিং: আপনি কী দয়া করে একটি ইন্টারেক্টিভ এসএসে পুনর্নির্দেশ বা পাইপিংয়ের অসুবিধাগুলি সম্পর্কিত কোনও লিঙ্ক সরবরাহ করতে পারেন?
আইজাক ক্লেইনম্যান

কিছুটা দেরি হলেও: এখানে আপনার ছদ্ম টার্মিনালের দরকার নেই, -Tপরিবর্তে বিকল্পটি ব্যবহার করুন।
ফ্লোরিয়ান

6

এই উত্তরগুলি অনেক পড়ার পরে আমি ভেবেছিলাম আমার ফলাফলটি ভাগ করে নেব। আমি যুক্ত সমস্ত কিছুই /bin/bashহেরডোকের আগে এবং এটি ত্রুটিটি আর দেয় না।

এটা ব্যবহার কর:

ssh user@machine /bin/bash <<'ENDSSH'
   hostname
ENDSSH

এর পরিবর্তে (ত্রুটি দেয়):

ssh user@machine <<'ENDSSH'
   hostname
ENDSSH

অথবা এটি ব্যবহার করুন:

ssh user@machine /bin/bash < run-command.sh

এর পরিবর্তে (ত্রুটি দেয়):

ssh user@machine < run-command.sh

অতিরিক্ত :

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

ssh -t user@machine "$(<run-command.sh)"

এবং আপনি যদি একটি ফাইলে পুরো সেশনটি লগ করতে চান logfile.log:

ssh -t user@machine "$(<run-command.sh)" | tee -a logfile.log

0

উইন্ডোজ / এমএসএস: ইউজার @ হোস্টের মাধ্যমে কিছু সংস্থার সার্ভারের সাথে সংযোগ স্থাপনের জন্য ইমাস 24.5.1 ব্যবহার করে উইন্ডোজের অধীনে আমার একই ত্রুটি ছিল। আমার সমস্যার সমাধানটি হ'ল "ট্র্যাম্প-ডিফল্ট-পদ্ধতি" ভেরিয়েবলটিকে "প্লিংক" এ সেট করে এবং যখনই আমি কোনও সার্ভারের সাথে সংযুক্ত থাকি আমি ssh প্রোটোকল বাদ দিই। এটি কাজ করার জন্য আপনার পিটিটিওয়ির প্লিংক.এক্সি ইনস্টল করা দরকার।

সমাধান

  1. এমএক্স কাস্টমাইজ-ভেরিয়েবল (এবং তারপরে এন্টার টিপুন)
  2. ট্রাম্প-ডিফল্ট-পদ্ধতি (এবং তারপরে আবার এন্টার চাপুন)
  3. পাঠ্য ক্ষেত্রে প্লিংক দিন এবং তারপরে বাফার প্রয়োগ করুন এবং সংরক্ষণ করুন
  4. যখনই আমি একটি রিমোট সার্ভার অ্যাক্সেস করার চেষ্টা করি আমি এখন Cxf / ব্যবহারকারীর @ হোস্ট: এবং তারপরে পাসওয়ার্ডটি ব্যবহার করি। উইন্ডোজটি আমার রিমোট সার্ভারে ইমাসসের অধীনে সংযোগটি এখন সঠিকভাবে করা হয়েছে।

-3

ssh -t foobar @ লোকালহোস্ট thycript.pl


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