বাশ-এ একটি কমান্ডের আগে পরিবেশের পরিবর্তনশীল সেট করা কোনও পাইপে দ্বিতীয় কমান্ডের জন্য কাজ করে না


351

প্রদত্ত শেলের মধ্যে সাধারণত আমি একটি ভেরিয়েবল বা ভেরিয়েবল সেট করেছিলাম এবং তারপরে একটি কমান্ড চালাতাম। সম্প্রতি আমি একটি কমান্ডের একটি পরিবর্তনশীল সংজ্ঞা প্রিপেন্ড করার ধারণা সম্পর্কে শিখেছি:

FOO=bar somecommand someargs

এটি কাজ করে ... ধরনের। যখন আপনি একটি LC_ * পরিবর্তনশীল পরিবর্তন করছি এটা কাজ করে না (যা কমান্ড প্রভাবিত বলে মনে হয়, কিন্তু না তার আর্গুমেন্ট, উদাহরণস্বরূপ, '[AZ] গৃহস্থালির কাজ রেঞ্জ) অথবা যখন thusly অন্য কমান্ড আউটপুট বংশীধ্বনিতুল্য:

FOO=bar somecommand someargs | somecommand2  # somecommand2 is unaware of FOO

আমি "এফইও = বার" এর সাহায্যেও কিছু কম্যান্ড 2 চালিয়ে দিতে পারি, যা কাজ করে তবে এতে অযাচিত নকল যোগ হয় এবং এটি ভেরিয়েবলের উপর নির্ভর করে ব্যাখ্যা করা যুক্তিগুলির সাথে সহায়তা করে না (উদাহরণস্বরূপ, '[অ্যাজ]')।

সুতরাং, একক লাইনে এটি করার একটি ভাল উপায় কী?

আমি এর আদেশে কিছু ভাবছি:

FOO=bar (somecommand someargs | somecommand2)  # Doesn't actually work

আমি অনেক ভাল উত্তর পেয়েছি! লক্ষ্যটি হ'ল এটিকে একটি ওয়ান-লাইনার রাখুন, পছন্দ হিসাবে "এক্সপোর্ট" ব্যবহার না করে। বাশের কাছে একটি কল ব্যবহার করার পদ্ধতিটি সামগ্রিকভাবে সেরা ছিল, যদিও এটিতে "এক্সপোর্ট" সহ প্রথম সংস্করণটি ছিল আরও কিছুটা কমপ্যাক্ট। পাইপের পরিবর্তে পুনঃনির্দেশ ব্যবহার করার পদ্ধতিটিও আকর্ষণীয়।


1
(T=$(date) echo $T)কাজ করবে
vp_arth

ক্রস-প্ল্যাটফর্মের (উইন্ডোজ সহ) স্ক্রিপ্ট বা এনএমপি-ভিত্তিক প্রকল্পগুলির (জেএস বা অন্য) প্রসঙ্গে আপনি ক্রস-এনভির মডিউলটি একবার দেখে নিতে পারেন ।
ফ্রাঙ্ক নোক

5
আমি আশা করছিলাম যে উত্তরগুলির মধ্যে একটিও ব্যাখ্যা করবে যে এটি কেন কেবল এই ধরণের কাজ করে, কেননা এটি কল করার আগে পরিবর্তনশীল রফতানির সমতুল্য নয়।
ব্রেচ্ট ম্যাচিয়েলস

4
কেন এখানে ব্যাখ্যা করা হয়েছে: স্ট্যাকওভারফ্লো.com
ব্রেচ্ট ম্যাচিলস

উত্তর:


317
FOO=bar bash -c 'somecommand someargs | somecommand2'

2
এটি আমার মানদণ্ডকে ("রফতানির প্রয়োজন ছাড়াই ওয়ান-লাইনার" সন্তুষ্ট করে) ... "বাশ-সি" (যেমন, প্রথম বন্ধনীর সৃজনশীল ব্যবহার) না বলে এটি করার কোনও উপায় নেই আমি তা গ্রহণ করি ?
মার্টিম্যাকজিভার

1
@ মার্টিম্যাকজিভার: আমি ভাবতে পারি না এমন কিছুই। এটি কোঁকড়া ধনুর্বন্ধনী সঙ্গে কাজ করবে না।
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

7
নোট করুন যে আপনি somecommandsudo হিসাবে চালানোর প্রয়োজন হলে , -Eভেরিয়েবল যদিও পাস করার জন্য আপনার sudo পতাকা পাস করতে হবে। কারণ ভেরিয়েবল দুর্বলতার পরিচয় দিতে পারে। stackoverflow.com/a/8633575/1695680
ThorSummoner

11
মনে রাখবেন যে আপনার কমান্ডটিতে ইতিমধ্যে দুটি স্তরের উক্তি রয়েছে তবে উদ্ধৃতি হেল্পের কারণে এই পদ্ধতিটি অত্যন্ত অসন্তুষ্টিজনক হয়ে উঠবে। সেই পরিস্থিতিতে সাবশেলে রফতানি করা আরও ভাল।
পুষ্পেন্দ্রে

বিজোড়: ওএসএক্স-তে, FOO_X=foox bash -c 'echo $FOO_X'প্রত্যাশিত হিসাবে কাজ করে তবে নির্দিষ্ট বর্ণের সাথে এটি ব্যর্থ হয়: DYLD_X=foox bash -c 'echo $DYLD_X'ইকোস ফাঁকা। দু'জনেই evalbash -c
mwag

209

পরিবর্তনশীল রফতানি সম্পর্কে কীভাবে তবে কেবল সাব-শেলের ভিতরে ?:

(export FOO=bar && somecommand someargs | somecommand2)

কীথের একটি বিন্দু রয়েছে, নিঃশর্তভাবে আদেশগুলি কার্যকর করতে, এটি করুন:

(export FOO=bar; somecommand someargs | somecommand2)

15
আমি ;বরং ব্যবহার করব &&; export FOO=barব্যর্থ হওয়ার কোন উপায় নেই ।
কিথ থম্পসন

1
@ মার্টিম্যাকগাইভার: &&বাম কমান্ডটি কার্যকর করে, তবে বাম কমান্ডটি সফল হলে ডান কমান্ডটি কার্যকর করে। ;উভয় কমান্ড নিঃশর্তভাবে কার্যকর করে। উইন্ডোজ ব্যাচ ( cmd.exeএর সমতুল্য) ;হয় &
কিথ থম্পসন

2
Zsh এ আমার এই সংস্করণটির জন্য রফতানি দরকার বলে মনে হচ্ছে না: (FOO=XXX ; echo FOO=$FOO) ; echo FOO=$FOOফলন FOO=XXX\nFOO=\n
রায়পুম

3
@ পোপপোপিনপ্যান্টস: সে ক্ষেত্রে কেন source(ওরফে .) ব্যবহার করবেন না ? এছাড়াও, এই দিনগুলিতে ব্যাকটিকগুলি আর ব্যবহার করা উচিত নয় এবং $(command)এটি ওয়াহায়ে নিরাপদ ব্যবহারের অন্যতম কারণ ।
0xC0000022L

3
এত সহজ, তবুও মার্জিত। এবং আমি আপনার উত্তর গ্রহণযোগ্য উত্তরের চেয়ে ভাল পছন্দ করি, কারণ এটি আমার বর্তমানের সমান একটি সাব শেল শুরু করবে (যা নাও হতে পারে bashতবে অন্য কিছু হতে পারে, উদাহরণস্বরূপ dash) এবং যদি আমার উদ্ধৃতি অবশ্যই ব্যবহার করা হয় তবে আমি কোনও সমস্যায় পড়ি না কমান্ডের মধ্যে আরগস ( someargs)।
মক্কি

45

আপনি এটি ব্যবহার করতে পারেন eval:

FOO=bar eval 'somecommand someargs | somecommand2'

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

আমরা যেমন কিছু নিয়মিত মতামত পাই, সম্ভবত এমন একটি বিকল্প দেওয়া ভাল evalযা প্রত্যেককে খুশি করবে এবং এই দ্রুত eval"কৌতুক" এর সমস্ত সুবিধা (এবং সম্ভবত আরও বেশি!) রয়েছে । শুধু একটি ফাংশন ব্যবহার করুন! আপনার সমস্ত আদেশ সহ একটি ফাংশন সংজ্ঞায়িত করুন:

mypipe() {
    somecommand someargs | somecommand2
}

এবং এটি আপনার পরিবেশের ভেরিয়েবলগুলির সাথে এটি কার্যকর করুন:

FOO=bar mypipe

7
@ আলফা: আপনি কি গৃহীত উত্তরকে হ্রাস করেছেন? কারণ এটি একই হিসাবে "সমস্যা" প্রদর্শন করে eval
gniourf_gniourf

10
@ আলফা: দুর্ভাগ্যক্রমে আমি আপনার সমালোচনার সাথে একমত নই। এই আদেশটি পুরোপুরি নিরাপদ। আপনি সত্যিই এমন লোকের মতো শোনেন যিনি একবার পড়েছেন evalযা খারাপ তা না বুঝেই মন্দ eval। এবং সম্ভবত আপনি এই উত্তরটি সর্বোপরি বুঝতে পারছেন না (এবং সত্যিই এটিতে কোনও ভুল নেই)। একই স্তরে: আপনি কি বলবেন যে lsএটি খারাপ কারণ for file in $(ls)খারাপ? (এবং হ্যাঁ, আপনি গৃহীত উত্তরকে হ্রাস করেননি এবং আপনি কোনও মন্তব্যও করেননি)। এসও কখনও কখনও কখনও যেমন একটি অদ্ভুত এবং অযৌক্তিক জায়গা।
gniourf_gniourf

7
@ আলফ: যখন আমি বলি আপনি সত্যিই এমন লোকের মতোevaleval শোনেন যিনি একবার পড়েছেন সে সম্পর্কে খারাপ কী তা না বুঝেই খারাপ , আমি আপনার বাক্যটি উল্লেখ করছি: কথা বলার সময় এই উত্তরটিতে সমস্ত সতর্কতা এবং ব্যাখ্যা নেই eval evalখারাপ বা বিপজ্জনক নয়; আর না bash -c
gniourf_gniourf

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

আমি একটি নতুন মন্তব্যে আমার উদ্বেগকে কেন্দ্রীভূত করতে আমার মন্তব্যগুলি সরিয়েছি: evalএটি সাধারণভাবে একটি সুরক্ষার সমস্যা (যেমন bash -cতবে কম স্পষ্ট), সুতরাং এর ব্যবহারের প্রস্তাব দেওয়ার উত্তরে বিপদগুলি উল্লেখ করা উচিত। অসতর্ক ব্যবহারকারীরা উত্তর ( FOO=bar eval …) নিতে এবং তাদের পরিস্থিতিতে এটি প্রয়োগ করতে পারে যাতে এটি সমস্যা উত্থাপন করে। তবে উত্তরদাতাদের পক্ষে স্পষ্টতই গুরুত্বপূর্ণ হওয়া উচিত যে আমি কোনও এবং উন্নতি করার চেয়ে তার এবং / অথবা অন্যান্য উত্তরগুলিকে হ্রাস করেছি কিনা figure আমি আগে যেমন লিখেছি, ন্যায়বিচারকে প্রধান উদ্বেগ হওয়া উচিত নয়; হচ্ছে কোন খারাপ অন্য কোন প্রদত্ত উত্তর চেয়ে আরো irregardless হয়।
আলফে

12

ব্যবহার env

উদাহরণস্বরূপ env FOO=BAR command,। নোট করুন পরিবেশ কার্যকর করার পরে পরিবেশের ভেরিয়েবলগুলি পুনরুদ্ধার / অপরিবর্তিত হবে command

শেল সাবস্টিটিউশনটি ঘটছে সে সম্পর্কে কেবল সতর্কতা অবলম্বন করুন, যদি আপনি $FOOএকই কমান্ড লাইনে স্পষ্টভাবে উল্লেখ করতে চান তবে আপনার এটির হাতছাড়া হওয়ার প্রয়োজন হতে পারে যাতে আপনার শেল ইন্টারপ্রেটার এটি চালানোর আগে প্রতিস্থাপনটি সম্পাদন না করে env

$ export FOO=BAR
$ env FOO=FUBAR bash -c 'echo $FOO'
FUBAR
$ echo $FOO
BAR

-5

শেল স্ক্রিপ্ট ব্যবহার করুন:

#!/bin/bash
# myscript
FOO=bar
somecommand someargs | somecommand2

> ./myscript

13
আপনার এখনও প্রয়োজন export; অন্যথায় $FOOএকটি শেল পরিবর্তনশীল, কোনো এনভায়রনমেন্ট ভেরিয়েবল, এবং সেইজন্য দৃশ্যমান হবে না somecommandবা somecommand2
কিথ থম্পসন

এটি কাজ করবে তবে এটি এক-লাইন কমান্ড থাকার উদ্দেশ্যকে হারাতে পারে (তুলনামূলকভাবে সহজ ক্ষেত্রে মাল্টি-লাইনার এবং / অথবা স্ক্রিপ্টগুলি এড়াতে আরও সৃজনশীল উপায়গুলি শিখার চেষ্টা করছি)) এবং কিথ কী বলেছে, যদিও কমপক্ষে রফতানি স্ক্রিপ্টের কাছে থেকে যায়।
মার্টিম্যাকজিভার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.