মেকফাইলে মাল্টলাইন বাশ কমান্ড


120

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

for i in `find`
do
    all="$all $i"
done
gcc $all

এছাড়াও, কেউ ব্যাখ্যা করতে পারেন কেন এমনকি সিঙ্গল-লাইন কমান্ডটি bash -c 'a=3; echo $a > file'টার্মিনালে সঠিকভাবে কাজ করে তবে মেকফিলের ক্ষেত্রে খালি ফাইল তৈরি করে?


4
দ্বিতীয় অংশটি পৃথক প্রশ্ন হওয়া উচিত। অন্য একটি প্রশ্ন যুক্ত করা কেবল গোলমাল সৃষ্টি করে।
l0b0

উত্তর:


136

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

foo:
    for i in `find`;     \
    do                   \
        all="$$all $$i"; \
    done;                \
    gcc $$all

তবে আপনি যদি কেবল findঅনুরোধের দ্বারা ফিরে আসা পুরো তালিকাটি নিতে চান এবং এটি পাস করতে চান তবে gccআপনার অবশ্যই কোনও মাল্টলাইন কমান্ডের প্রয়োজন নেই:

foo:
    gcc `find`

অথবা, আরও শেল-প্রচলিত $(command)পদ্ধতির ব্যবহার করে ( $যদিও পালানোর বিষয়টি লক্ষ্য করুন ):

foo:
    gcc $$(find)

2
মাল্টলাইনের জন্য, আপনাকে এখনও ডলারের চিহ্নগুলি থেকে বাঁচতে হবে, অন্যত্র মন্তব্যগুলিতে উল্লিখিত হয়েছে।
ট্রিপলি

1
হ্যাঁ, একটি সংক্ষিপ্ত উত্তর 1. $: = $$ 2. T বিটিডাব্লু বাশ ছেলের সাথে মাল্টলাইন যুক্ত করুন সাধারণত `ফাইন্ড` কল $$ (সন্ধান করুন) প্রতিস্থাপন করার পরামর্শ দেন
ইয়াহেন ইয়াকিমোভিচ ১

89

প্রশ্নে ইঙ্গিত হিসাবে, প্রতিটি উপ-কমান্ড নিজস্ব শেল চালিত হয় । এটি অ-তুচ্ছ শেল স্ক্রিপ্টগুলি কিছুটা অগোছালো করে তোলে - তবে এটি সম্ভব! সমাধানটি হ'ল আপনার স্ক্রিপ্টকে একীভূত করা কী কোনও মেকেলকে একটি একক সাব-কমান্ড (একক লাইন) বিবেচনা করবে।

মেকফিলের মধ্যে শেল স্ক্রিপ্টগুলি লেখার জন্য পরামর্শ:

  1. এর $পরিবর্তে স্ক্রিপ্টের ব্যবহার এড়িয়ে চলুন$$
  2. ;কমান্ডের মধ্যে সন্নিবেশ করে স্ক্রিপ্টটিকে একক লাইন হিসাবে কাজ করতে রূপান্তর করুন
  3. আপনি যদি একাধিক লাইনে স্ক্রিপ্টটি লিখতে চান তবে এর সাথে শেষের দিকে লাইনটি এড়িয়ে চলুন \
  4. বৈকল্পিকভাবে দিয়ে শুরু set -eসাব-কমান্ড ব্যর্থতা উপর টি থামিয়ে দিতে সাথে তাল মিলিয়ে এর বিধান
  5. এটি সম্পূর্ণরূপে alচ্ছিক, তবে আপনি একাধিক লাইন সিকোয়েন্সের সংহতকরণের সাথে জোর দিয়ে ()বা স্ক্রিপ্টটি {}বন্ধন করতে পারেন - এটি কোনও সাধারণ মেকফিল কমান্ড অনুক্রম নয় that

এখানে ওপি দ্বারা অনুপ্রাণিত একটি উদাহরণ:

mytarget:
    { \
    set -e ;\
    msg="header:" ;\
    for i in $$(seq 1 3) ; do msg="$$msg pre_$${i}_post" ; done ;\
    msg="$$msg :footer" ;\
    echo msg=$$msg ;\
    }

4
আপনি প্রক্রিয়া প্রতিস্থাপনেরSHELL := /bin/bash মতো BASH- নির্দিষ্ট বৈশিষ্ট্যগুলি সক্ষম করতে আপনার মেকফিলের মধ্যে থাকতে পারেন ।
ব্রেন্ট ব্র্যাডবার্ন

8
সূক্ষ্ম বিন্দু: অজানা আদেশ হিসাবে {ব্যাখ্যাটি রোধ করার জন্য স্থানটি গুরুত্বপূর্ণ {set
ব্রেন্ট ব্র্যাডবার্ন

3
সূক্ষ্ম বিন্দু # 2: মেকফাইলে এটি সম্ভবত কিছু যায় আসে না, তবে মোড়ানো {}এবং এর মধ্যে ()পার্থক্যটি যদি আপনি মাঝে মাঝে স্ক্রিপ্টটি অনুলিপি করতে চান এবং সরাসরি শেল প্রম্পট থেকে চালাতে চান তবে এটি একটি বড় পার্থক্য করে। আপনি ভেরিয়েবলগুলি ঘোষণা করে এবং বিশেষত এর setঅভ্যন্তরে এর সাথে রাষ্ট্র পরিবর্তন করে আপনার শেল ইনস্ট্যান্সটিতে সর্বনাশ করতে পারেন {}()স্ক্রিপ্টটিকে আপনার পরিবেশ পরিবর্তন করতে বাধা দেয় যা সম্ভবত পছন্দনীয়। উদাহরণ ( এই আপনার শেল অধিবেশনটিকে শেষ করবে ): { set -e ; } ; false
ব্রেন্ট ব্র্যাডবার্ন

আপনি নিম্নলিখিত ফর্মটি ব্যবহার করে মন্তব্যগুলি অন্তর্ভুক্ত করতে পারেন command ; ## my comment \` (the comment is between :; `এবং` \ `)। এটি যদি আপনার কমান্ডটি ম্যানুয়ালি চালিত হয় তবে (কপি-পেস্ট করে), কমান্ড ইতিহাসে মন্তব্যটি এমনভাবে অন্তর্ভুক্ত করবে যাতে কমান্ডটি ভেঙে যায় (যদি আপনি এটি পুনরায় ব্যবহার করার চেষ্টা করেন)। [দ্রষ্টব্য: ব্যাকটিকের ভিতরে ব্যাকস্ল্যাশ ব্যবহারের কারণে এই মন্তব্যটির জন্য সিনট্যাক্স হাইলাইটিংটি ভেঙে গেছে]]
ব্রেন্ট ব্র্যাডবার্ন

আপনি যদি মেকফিলের অভ্যন্তরে ব্যাশ / পার্ল / স্ক্রিপ্টে কোনও স্ট্রিং ভাঙতে চান তবে স্ট্রিং কোট, ব্যাকস্ল্যাশ, নিউলাইন, (কোনও ইনডেন্টেশন নয়) ওপেন স্ট্রিং কোট বন্ধ করুন। উদাহরণ; পার্ল-কোটের মুদ্রণ 1; কোট ব্যাকস্ল্যাশ নিউজলাইন কোট 2 মুদ্রণ
মোশ

2

শুধু আদেশগুলি চাওয়ার সাথে কী দোষ?

foo:
       echo line1
       echo line2
       ....

এবং আপনার দ্বিতীয় প্রশ্নের জন্য, আপনাকে পরিবর্তে, অর্থাৎ $ব্যবহার করে পালাতে $$হবে bash -c '... echo $$a ...'

সম্পাদনা: আপনার উদাহরণটি একটি একক লাইনের স্ক্রিপ্টে এভাবে আবার লেখা যেতে পারে:

gcc $(for i in `find`; do echo $i; done)

5
"প্রতিটি কমান্ডের নিজস্ব শেল চালানো হয়" এর কারণ হিসাবে, আমাকে কমান্ড 2-এ কমান্ড 1 এর ফলাফল ব্যবহার করা দরকার। যেমন উদাহরণ।
জোফসি

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

+1, বিশেষত সরলীকৃত সংস্করণের জন্য। এবং এটি কি ঠিক `cc gcc` find doing করার মতো নয়?
এলদার আবুসালিমভ

1
হ্যাঁ, তাই তবে আপনি অবশ্যই 'ইকো' এর চেয়ে আরও জটিল কিছু করতে পারবেন।
জেস্পেআর

2

অবশ্যই, মেকফিল লেখার যথাযথ উপায়টি হ'ল নথিগুলি যা কোন উত্সগুলির উপর নির্ভর করে। তুচ্ছ ক্ষেত্রে, প্রস্তাবিত সমাধানটি fooনিজের উপর নির্ভর করবে , তবে অবশ্যই, makeএকটি বিজ্ঞপ্তি নির্ভরতা হ্রাস করতে যথেষ্ট স্মার্ট। তবে আপনি যদি আপনার ডিরেক্টরিতে একটি অস্থায়ী ফাইল যুক্ত করেন তবে এটি "ম্যাজিকালি" নির্ভরতা শৃঙ্খলার অংশ হয়ে যাবে। একবার এবং সবার জন্য নির্ভরতার একটি সুস্পষ্ট তালিকা তৈরি করা আরও ভাল, সম্ভবত কোনও স্ক্রিপ্টের মাধ্যমে।

জিএনইউ মেক জানে কীভাবে gccএকটি সেট .cএবং .hফাইলগুলির সেট থেকে এক্সিকিউটেবল উত্পাদন করতে চালানো যায় , তাই সম্ভবত আপনার যা প্রয়োজন তার পরিমাণের পরিমাণ

foo: $(wildcard *.h) $(wildcard *.c)

1

ওএনএসএইচএল নির্দেশ একই শেল ডাকে অনুরোধে কার্যকর করতে একাধিক লাইন রেসিপি লেখার অনুমতি দেয়।

SOURCE_FILES = $(shell find . -name '*.c')

.ONESHELL:
foo: ${SOURCE_FILES}
    for F in $^; do
        gcc -c $$F
    done

যদিও একটি ত্রুটি রয়েছে: বিশেষ উপসর্গের অক্ষর ('@', '-', এবং '+') আলাদাভাবে ব্যাখ্যা করা হয়।

https://www.gnu.org/software/make/manual/html_node/One-Shell.html

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