পাইপ থেকে ব্যবহারকারী ইনপুট কীভাবে পড়বেন?


9

ধরে নেওয়া যাক আমার confirmation.shনীচের কন্টেন্ট সহ একটি ফাইল আছে :

#!/bin/bash
echo -n "Are you sure [Y/n]? "
read line
case "$line" in
    n|N) echo "smth"
        ;;
    y|Y) echo "smth"
        ;;
esac

এবং আমি এই স্ক্রিপ্টটি নিম্নলিখিত উপায়ে চালাতে চাই:

cat confirmation.sh | sh

আমি দেখছি Are you sure [Y/n]?এবং স্ক্রিপ্ট বাধাগ্রস্ত হয়েছে। সমস্যা কি?


2
আপনার কাছে /bin/bashঠুং লাইনে, এখনো আপনি একটি ব্যবহার .shএক্সটেনশান এবং নল করতে স্ক্রিপ্ট চেষ্টা sh। আপনার যে কোডটি রয়েছে সেগুলি উভয়ের সাথেই সামঞ্জস্যপূর্ণ না হলেও সমস্যাটি নয় poin
গ্রীম

উত্তর:


8

অন্যদের বলেছি, এই কারণ stdinএর shপাইপ থেকে পড়তে পুনঃনির্দেশিত হয়েছে, এটি টার্মিনালে সংযুক্ত নেই যেমন স্বাভাবিকভাবে হতে হবে। এটিকে ঘিরে ধরার জন্য আপনি যা করতে পারেন /dev/ttyতা হ'ল টার্মিনাল থেকে স্ক্রিপ্টটি পড়তে বাধ্য করা। উদাহরণ:

#!/bin/sh

read -p "Are you sure [Y/n]?" line </dev/tty
case "$line" in
  y|Y) echo "confirmed"
    ;;
  *) echo "not confirmed"
    ;;
esac

সাধারণত আপনি কেবল তখনই এটি করতে পারবেন যদি আপনি বিশেষভাবে লোকদের ইনপুট স্ক্রিপ্ট করা থেকে বিরত রাখতে চান, যেমন:

echo Y | sh confirmation.sh

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


2
sh 3<<CONFIRM /dev/fd/3
    $(cat ./confirmation.sh)
CONFIRM

sh 3<./confirmation.sh /dev/fd/3

দ্রষ্টব্য: উপরোক্ত দুটি উদাহরণে আমাকে সংশোধন করার জন্য @ গ্র্যামিকে ধন্যবাদ জানাই ...

আপনি stdinপরিষ্কার রাখলে এটি করা অনেক সহজ ।

2<./confirmation.sh . /dev/stderr

বা, যেহেতু একটি টার্মিনালের 0 1 2 সমস্ত একই ফাইল, কেবল যুক্ত করুন:

read line <&2

এবং তোমার

cat ./confirmation.sh | sh

ঠিক কাজ করে।


আমি এগুলির কোনওটি শেষের থেকে আলাদা হয়ে কাজ করতে পারি না।
গ্রামীণ

অদ্ভুত, তারা সবাই আমার জন্য কাজ করেছিল ... আমি কোনও কিছুর মাঝে আছি, তবে ... 10 বা কয়েক মিনিটের মধ্যে আমি আবার পরীক্ষা করতে পারি। এরই মধ্যে ... আপনার কমেন্টটি বোল্ড হতে পারে? আমি ভুল তথ্য ছড়িয়ে দিতে পছন্দ করি না।
মাইক্রোজার্ভ 26'14

@ গ্র্যাম - কেন জানি না যে আমি প্রথমবার এটি কেন মিস করলাম - শপথ করতে পারলাম আমি একই সাথে তাদের সমস্ত পরীক্ষা করেছি - তবে প্রথম দুটি সঠিকভাবে পরিচালনা করার জন্য পরিবর্তনের দরকার পড়ে। ধন্যবাদ.
মাইক্রোসার্ভ

দেখতে দেখতে দুর্দান্ত, এটি এখনও টার্মিনাল থেকে পড়ে না যখন আমি উত্স থেকে উত্স stderr। আমি সম্ভবত যদিও করা উচিত, আমি বুঝতে পারি না কেন।
গ্রিমে

@ গ্র্যাম - অদ্ভুত - আমি এটি ড্যাশ শ জেডএস এবং বাশ দিয়ে চেষ্টা করেছি। সব কাজ।
মাইকজার্ভ

0

এটি আমার স্ক্রিপ্টে পাইপ দেওয়ার জন্য একক যুক্তির পক্ষে কাজ করেছে:

if [ -p /dev/stdin ]; then set -- "$( cat )"; fi

তারপরে আমি পাইপযুক্ত ডেটা অবস্থানগত আর্গুমেন্টে প্রবেশ করতে পারি ( $1), যা আমার অন্যান্য স্ক্রিপ্টের কাজের সাথে সামঞ্জস্যপূর্ণ।


থেকে info test:

[ -p /dev/stdin ]: -p FILEসত্য যদি ফাইলটি বিদ্যমান থাকে এবং নামযুক্ত পাইপ হয়।


-1

সংক্ষিপ্ত উত্তরটি আপনি পারবেন না। পাইপ stdout স্টিনে পুনঃনির্দেশ করে, সুতরাং আপনি ইতিমধ্যে একটি ইন্টারেক্টিভ স্ক্রিপ্ট চালাতে পারবেন না, যেমন আপনি পাইপ বিবৃতিতে প্রথম কমান্ড থেকে দ্বিতীয় কমান্ডের ইনপুট হিসাবে আউটপুটটিকে পুনঃনির্দেশিত করেছেন।

আপনি হয়ত এরকম কিছু করতে চাইছেন:

cat confirmation.sh > ask.sh && sh ask.sh

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