বর্তমান শেলের মধ্যে একটি কমান্ডের আউটপুট কীভাবে কার্যকর করা যায়?


92

আমি source(ওরফে .) ইউটিলিটি সম্পর্কে ভালভাবে অবগত রয়েছি , যা কোনও ফাইল থেকে সামগ্রীগুলি নিয়ে যায় এবং বর্তমান শেলের মধ্যে এগুলি কার্যকর করে ute

এখন, আমি কিছু পাঠ্য শেল কমান্ডে রূপান্তর করছি এবং তারপরে সেগুলি চালিয়ে যাচ্ছি:

$ ls | sed ... | sh

lsএটি কেবল একটি এলোমেলো উদাহরণ, মূল পাঠ্যটি যে কোনও কিছু হতে পারে। sedখুব, পাঠ্য রূপান্তরের জন্য একটি উদাহরণ। মজার বিষয় হল sh। আমি যা পাই পাইপ করি shএবং এটি এটি চালায়।

আমার সমস্যাটি হ'ল এর অর্থ একটি নতুন সাব শেল শুরু করা। আমি বরং আমার বর্তমান শেলের মধ্যে কমান্ডগুলি চালিত করতে চাই। আমি source some-fileযদি কোনও পাঠ্য ফাইলে কমান্ডগুলি পাই তবে আমি এটি করতে সক্ষম হব।

নোংরা লাগছে বলে আমি কোনও টেম্প ফাইল তৈরি করতে চাই না।

বিকল্পভাবে, আমি আমার সাব শেলটি আমার বর্তমান শেলের মতো একই বৈশিষ্ট্যগুলি দিয়ে শুরু করতে চাই।

হালনাগাদ

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

দু: খিত আপডেট

আহ, /dev/stdinজিনিসটি দেখতে খুব সুন্দর লাগছিল, তবে আরও জটিল ক্ষেত্রে এটি কার্যকর হয়নি।

সুতরাং, আমি এটি আছে:

find . -type f -iname '*.doc' | ack -v '\.doc$' | perl -pe 's/^((.*)\.doc)$/git mv -f $1 $2.doc/i' | source /dev/stdin

যা নিশ্চিত করে যে সমস্ত .docফাইলের এক্সটেনশন হ্রাস পেয়েছে।

এবং যা ঘটনাক্রমে হ্যান্ডেল করা যেতে পারে xargs, কিন্তু এটি বিষয় ছাড়াও।

find . -type f -iname '*.doc' | ack -v '\.doc$' | perl -pe 's/^((.*)\.doc)$/$1 $2.doc/i' | xargs -L1 git mv

সুতরাং, আমি যখন প্রাক্তনটিকে চালিত করি, এটি এখনই প্রস্থান করবে, কিছুই হয় না।


আপনি যখন কোনও টেম্পল ফাইলটি প্রথমে পাইপ করেন এবং তারপরে উত্স উত্পন্ন করেন তখন কি আপনার জটিল কমান্ডটি কাজ করে? যদি তা না হয়, উত্পন্ন আউটপুট নিয়ে সমস্যা কী? আপনার ফাইলের নামগুলিতে ফাঁক থাকলে বা নির্দিষ্ট ক্রমগুলি যথাযথভাবে অব্যাহত না থাকলে আপনার কমান্ডের আউটপুট কাজ করবে না। আমি সর্বনিম্ন কমপক্ষে $ 1 এবং $ 2. ডক এর কোট যুক্ত করতে চাই।
কালেব পেডারসন

আসল শেলটিতে এটি চালানোর কোনও ভাল কারণ আছে কি? - এই উদাহরণগুলি বর্তমান শেলটি হেরফের করে না যাতে এটি করে আপনি কিছুই লাভ করেন না। দ্রুত সমাধান আপনি একটি ফাইল এবং যে যদিও ফাইল উৎস আউটপুট পুনর্নির্দেশ হয়
টি

@ কালেব আউটপুট ঠিক আছে runs এই বিশেষ ক্ষেত্রে, আমি sh পাইপ এমনকি যদি। ফাইলের নামগুলি স্থান-নিরাপদ, তবে লক্ষ করার জন্য ধন্যবাদ। আসল শেলটিতে @ নোট গিট এনভায়রনমেন্ট ভেরিয়েবল। এবং আবার, এই মাত্র উদাহরণ। প্রশ্ন জীবনের জন্য।
kch

আশেপাশে আটকে থাকার জন্য নির্ধারিত ভেরিয়েবলগুলির প্রয়োজন হলে সোর্স / দেব / স্টিডিন আমার পক্ষে কাজ করে না। geirha freenode ব্যাশ উপর আমাকে ইশারা mywiki.wooledge.org/BashFAQ/024 ও প্রস্তাবিত আমি একটি প্রক্রিয়া প্রতিকল্পন উৎস চেষ্টা <(কমান্ড) যা আমার জন্য কাজ
srcerer

উত্তর:


88
$ ls | sed ... | source /dev/stdin

আপডেট: এটি ব্যাশ ৪.০, পাশাপাশি টিসিএস এবং ড্যাশ (যদি আপনি পরিবর্তন sourceকরেন .) তে কাজ করে। স্পষ্টতই এটি ব্যাগ 3.2-তে বগি ছিল। থেকে ব্যাশ 4.0 রিলিজ নোট :

একটি বাগ স্থির করে যার কারণে caused ' নিয়মিত ফাইল যেমন ডিভাইস বা নামযুক্ত পাইপগুলি থেকে আদেশগুলি পড়তে এবং সম্পাদন করতে ব্যর্থ হতে পারে।


ওহ, এবং যেহেতু আপনি শেলগুলি তালিকাবদ্ধ করছেন, এটি zsh এও কাজ করে।
kch

4
আমি ভেবেছিলাম এটি জ্ঞানহীন ছিলাম যতক্ষণ না আমি এটি এমএসএস / মিংডব্লুতে পরীক্ষা করে দেখি (যেখানে কোনও ডিভ / ফোল্ডার নেই (বা এমনকি ডিভাইস নেই)! আমি অনেকগুলি মিশ্রণ, $ ()) এবং ব্যাকটিক্স tried tried ব্যবহার করেছিলাম tried , সুতরাং আমি অবশেষে কেবলমাত্র একটি টেম্পল ফাইলে আউটপুট পুনঃনির্দেশ করলাম, টেম্প ফাইলটি সসোর্স করলাম এবং এটি মুছে ফেলা হয়েছে Bas মূলত "সেড ...> /tmp/$$.tmp &&। /tmp/$$.tmp && rm / tmp / t। tmp "। টেম্প ফাইল ছাড়া যে কেউ
এমএসএস

10
কেবলমাত্র একটি মন্তব্য: এটি প্রত্যাশার মতো রফতানি বিবৃতি পরিচালনা করবে বলে মনে হয় না। যদি পাইপযুক্ত স্ট্রিংয়ের একটি রফতানি বিবৃতি থাকে, তবে এক্সপোর্টর ভেরিয়েবলটি আপনার টার্মিনাল পরিবেশে পরে পাওয়া যায় না, যেখানে ইওল রফতানিও পুরোপুরি কার্যকরভাবে কাজ করে।
ফিল

Lastpipe বিকল্প সেট ছাড়া ব্যাশ, এই মাত্র মত একটি subshell সৃষ্টি | bashwould
যা অন্য লোক

4
প্রদত্ত যে ম্যাকোস এক্স এর সাধারণত বশ থাকে 2.২ (সম্ভবত ইয়োসামাইটে 4.0.০?), এবং আমার ব্যবহারের ক্ষেত্রে লাস্টপাইপ ট্রিকির প্রয়োজন ('রফতানি' যুক্ত করার জন্য প্রতিটি লাইনের প্রাক-প্রসেসিং করে কোনও ফাইলের সমস্ত ভেরিয়েবলগুলি রফতানি করা) আমি বেছে নিয়েছি eval "$(sed ...)"পদ্ধতির সাথে যেতে - তবে 3.2 বাগ হেড-আপের জন্য ধন্যবাদ!
অ্যালেক্স দুপুয়

135

evalকমান্ড এই খুব উদ্দেশ্যে বিদ্যমান।

eval "$( ls | sed... )"

বাশ ম্যানুয়াল থেকে আরও :

স্পষ্ট

          eval [arguments]

আর্গুমেন্টগুলি একক কমান্ডে একত্রে সংযুক্ত করা হয়, যা পরে পড়া এবং কার্যকর করা হয় এবং এর প্রস্থান স্থিতিটি eval এর প্রস্থান স্থিতি হিসাবে ফিরে আসে। যদি কোনও যুক্তি বা খালি আর্গুমেন্ট না থাকে তবে ফেরতের স্থিতি শূন্য।


8
এখানে কেবলমাত্র সমস্যাটি হ'ল আপনার কমান্ডগুলি পৃথক করার জন্য আপনাকে সন্নিবেশ করতে হতে পারে; আমি এই পদ্ধতিটি নিজেই এআইএক্স, সান, এইচপি এবং লিনাক্সে কাজ করতে ব্যবহার করি।
টঙ্কটালাস

ট্যাঙ্কটালাস, এই মন্তব্যের জন্য ধন্যবাদ, এটি আমার স্ক্রিপ্টটির কাজ করেছে। আমার মেশিনে ইভাল নিউলাইনগুলিতে কমান্ড আলাদা করে না এবং উত্স ব্যবহার করে এমনকি আধা-কলোনগুলি দিয়েও কাজ করে না। আধা-কলোনগুলির সাথে ইভাল হ'ল সমাধান। আমি আশা করি আমি আপনাকে কিছু পয়েন্ট দিতে পারতাম।
মিলান বাবুভকভ

4
@ মিলানবাবুউককভ: আমি তাকে আপনার জন্য স্থান দিয়েছি ;-)
ফিল

4
এটি দুর্দান্ত। যাইহোক, আমার ব্যবহারের ক্ষেত্রে, আমি আমার $ () এর চারপাশে উদ্ধৃতিগুলি eval "$( ssh remote-host 'cat ~/.bash_profile' )"রেখেছিলাম : নোট করুন যে আমি প্রকৃতপক্ষে ব্যাশ ব্যবহার করছি 3..২।
জাচারি মারে

4
এটি আমার পক্ষে কাজ করে যেখানে গৃহীত উত্তরটি দেয় নি।
ড্যান টেনেনবাউম

37

বাহ, আমি জানি এটি একটি পুরানো প্রশ্ন, তবে আমি সম্প্রতি একই সঠিক সমস্যাটি পেয়েছি (আমি এখানে এসেছি)।

যাইহোক - আমি source /dev/stdinউত্তরটি পছন্দ করি না তবে আমি মনে করি আমি এর চেয়ে ভাল উত্তর পেয়েছি। এটি আসলে ছদ্মবেশী সহজ:

echo ls -la | xargs xargs

ভাল, তাই না? প্রকৃতপক্ষে, এটি এখনও আপনি যা চান তা করেন না, কারণ আপনার যদি একাধিক লাইন থাকে তবে এটি প্রতিটি কমান্ড পৃথকভাবে চালানোর পরিবর্তে একটি একক কমান্ডে যুক্ত করে। সুতরাং আমি যে সমাধানটি পেয়েছি তা হ'ল:

ls | ... | xargs -L 1 xargs

-L 1বিকল্পটি (অধিকতম) ব্যবহার কমান্ড সঞ্চালনের প্রতি 1 লাইন মানে। দ্রষ্টব্য: যদি আপনার লাইনটি একটি পূর্ববর্তী স্থানের সাথে শেষ হয়, তবে এটি পরবর্তী লাইনের সাথে সংযুক্ত হবে! সুতরাং নিশ্চিত করুন যে প্রতিটি লাইন একটি ফাঁকা স্থানের সাথে শেষ হয়েছে।

অবশেষে, আপনি করতে পারেন

ls | ... | xargs -L 1 xargs -t

কোন আদেশগুলি কার্যকর করা হয় তা দেখতে (-টি হ'ল ভার্বোস)।

আশা করি কেউ এই পড়েন!


31

প্রক্রিয়া প্রতিস্থাপন ব্যবহার করার চেষ্টা করুন , যা কোনও আদেশের আউটপুটকে অস্থায়ী ফাইলের সাথে প্রতিস্থাপন করে যা পরে উত্সাহিত করা যেতে পারে:

source <(echo id)

7
এটি কোন ধরণের যাদু?
পলোটোরেনস

4
এটি আমার প্রথম চিন্তাও ছিল। যদিও আমি ইওল সমাধানটি আরও ভাল পছন্দ করি। @ পাওলো টরেনস <(xyz) কেবল xyz সম্পাদন করে এবং <(xyz) এর পরিবর্তে একটি ফাইলের নামের সাথে xyz আউটপুট লিখবে। এটি কীভাবে কাজ করে তা বোঝার জন্য সহজ: উদাহরণস্বরূপ: echo <(echo id)আউটপুট প্রদান /dev/fd/12(12 উদাহরণ উদাহরণ), cat <(echo id)আউটপুট প্রদান idএবং তারপরে source <(echo id)কেবল লেখার মতো একই আউটপুট প্রদানid
নেটিগার

4
@ পাওলো টরেন্সকে এটিকে প্রক্রিয়া প্রতিস্থাপন বলা হয় । অফিসিয়াল ব্যাখ্যার জন্য লিঙ্কযুক্ত ডকস দেখুন, তবে সংক্ষিপ্ত উত্তরটি হ'ল "<()" একটি বিশেষ বাক্য গঠন যা এই জাতীয় কেসগুলি মাথায় রেখে তৈরি করা হয়েছিল।
মার্ক স্টসবার্গ

4
@ মার্কস্টোসবার্গ, আপনি কি জানেন যে এটি কোনও বিশেষ বাক্য গঠন বা কেবল একটি সাবসেল (...)পুনঃনির্দেশিত?
পলোটোরেনস

4
@ পাওলো টরেনস, এটি কেবল প্রক্রিয়া প্রতিস্থাপনের জন্য একটি বিশেষ বাক্য গঠন।
মার্ক স্টসবার্গ

6

আমি বিশ্বাস করি যে এটি প্রশ্নের "সঠিক উত্তর":

ls | sed ... | while read line; do $line; done

যে, একটি whileলুপ মধ্যে পাইপ করতে পারেন ; readকমান্ড কমান্ড তার থেকে এক লাইন লাগে stdinএবং পরিবর্তনশীল বরাদ্দ করুন $line$lineতারপরে লুপের মধ্যে সম্পাদিত কমান্ডটি পরিণত হয়; এবং এটির ইনপুটটিতে আর কোনও লাইন না পাওয়া পর্যন্ত এটি অব্যাহত থাকে।

এটি এখনও কিছু নিয়ন্ত্রণ কাঠামোর (অন্য লুপের মতো) সাথে কাজ করবে না, তবে এটি এই ক্ষেত্রে বিলে ফিট করে।


5
`ls | sed ...`

আমি সাজানোর মতো অনুভূতিটি সুন্দর ls | sed ... | source -হবে তবে দুর্ভাগ্যক্রমে এর অর্থ sourceবোঝা -যায় না stdin


মার্ক 4-এর উত্তর দেখার পরেও কি মনে হয় না যে এই মুহুর্তে আমাদের মুখে এটি ঠিক ছিল?
kch

হ্যাঁ, হ্যাঁ আমি মনে করি না যে স্টাফ বিদ্যমান।
বিশ্রামের

1

আমি মনে করি আপনার সমাধানটি ব্যাকটিক্স সহ কমান্ড প্রতিস্থাপন: http://tldp.org/LDP/Bash-Beginners- গুইড / html/sect_03_04.html

বিভাগ 3.4.5 দেখুন


4
আপনি যদি ব্যাশ ব্যবহার করছেন তবে $( )সিনট্যাক্সটি পছন্দ করা যেতে পারে। 'কোর্সে ব্যাকটিক্স আরও শেলগুলিতে কাজ করে ...
ডিএমকে --- --- প্রাক্তন মডারেটর বিড়ালছানা

6
pos (কমান্ড) এবং $ ((1 + 1)) সমস্ত পোস্টিক্স শেলগুলিতে কাজ করে। আমি মনে করি অনেকগুলি ভিমকে সিনট্যাক্স ত্রুটি হিসাবে চিহ্নিত করে ফেলে দেওয়া হয়েছে, তবে এটি কেবল কারণ ভিম মূল বোর্ন শেলটি হাইলাইট করছে যা খুব কম ব্যবহার করে। ভিমটি হাইলাইট করতে সঠিকভাবে এটি আপনার .vimrc এ রাখুন: আসুন g: is_posix = 1
পিক্সেলবিট

1

ব্যাশ ৩.২ (ম্যাকোস)-এ মার্ক4-এর সমাধানটি ব্যবহার করতে এখানে উদাহরণ হিসাবে পাইপলাইনের পরিবর্তে একটি স্ট্রিং ব্যবহার করা যেতে পারে:

. /dev/stdin <<< "$(grep '^alias' ~/.profile)"

বা ব্যাকটিক্স ব্যবহার করুন:। / dev / stdin <<< `গ্রেপ '^ ওরফে' ~ /। প্রোফাইল of
উইলিয়াম এইচ। হুপার

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