মেকফাইলে শেল কমান্ড কীভাবে ব্যবহার করবেন


102

আমি lsঅন্যান্য কমান্ডের ফলাফল ব্যবহার করার চেষ্টা করছি (যেমন প্রতিধ্বনি, আরএসএনসি):

all:
    <Building, creating some .tgz files - removed for clarity>
    FILES = $(shell ls)
    echo $(FILES)

তবে আমি পেয়েছি:

make
FILES = Makefile file1.tgz file2.tgz file3.tgz
make: FILES: No such file or directory
make: *** [all] Error 1

আমি চেষ্টা করেছিলাম echo $$FILES, echo ${FILES}এবং echo $(FILES), কোনও ভাগ্য ছাড়াই।

উত্তর:


157

সঙ্গে:

FILES = $(shell ls)

এর নীচে ইন্টেন্টেড all, এটি একটি বিল্ড কমান্ড। সুতরাং এটি প্রসারিত হয় $(shell ls), তারপরে কমান্ড চালানোর চেষ্টা করে FILES ...

যদি FILESকোনও makeভেরিয়েবল হিসাবে বিবেচিত হয় , তবে এই ভেরিয়েবলগুলি রেসিপি অংশের বাইরে নির্ধারণ করা দরকার, যেমন:

FILES = $(shell ls)
all:
        echo $(FILES)

অবশ্যই, তার মানে তাদের FILES"থেকে আউটপুট সেট করা হবে ls" আগে যে কমান্ড .tgz ফাইল তৈরি কোন চলছে। (যদিও কাজ নোট হিসাবে পরিবর্তনশীল প্রতিটি সময় পুনরায় প্রসারণ করা হয়, তাই শেষ পর্যন্ত এটি .tgz ফাইল অন্তর্ভুক্ত করা হবে; কিছু তৈরি করে বৈকল্পিক FILES := ...এড়াতে হবে, দক্ষতা এবং / বা নির্ভুলতার জন্য। 1 )

যদি FILESশেল ভেরিয়েবল হিসাবে বিবেচনা করা হয়, আপনি এটি সেট করতে পারেন তবে আপনার শেল-ইজে এগুলি করতে হবে, কোনও ফাঁকা জায়গা ছাড়াই এবং উদ্ধৃত হওয়া:

all:
        FILES="$(shell ls)"

তবে, প্রতিটি লাইন একটি পৃথক শেল দ্বারা চালিত হয়, সুতরাং এই পরিবর্তনশীলটি পরবর্তী লাইনে টিকবে না, সুতরাং আপনাকে অবশ্যই এটি অবিলম্বে ব্যবহার করতে হবে:

        FILES="$(shell ls)"; echo $$FILES

এটি প্রথমে কিছুটা নিরীহ যেহেতু শেলটি *আপনার জন্য প্রথমে প্রসারিত হবে (এবং অন্যান্য শেল গ্লোব এক্সপ্রেশন), সুতরাং আপনি ঠিক করতে পারেন:

        echo *

আপনার শেল কমান্ড হিসাবে

পরিশেষে, একটি সাধারণ নিয়ম হিসাবে (এই উদাহরণের জন্য সত্যই প্রযোজ্য নয়): মন্তব্যগুলিতে এস্পারেন্টো নোট হিসাবে , আউটপুটটি ব্যবহার করা lsপুরোপুরি নির্ভরযোগ্য নয় (কিছু বিবরণ ফাইলের নাম এবং কখনও কখনও এমনকি সংস্করণেও নির্ভর করে ls; lsআউটপুট স্যানিটাইজ করার প্রয়াসের কিছু সংস্করণ) কিছু ক্ষেত্রে)। সুতরাং, l0b0 এবং আইডিলিক নোট হিসাবে, আপনি যদি জিএনইউ ব্যবহার করছেন তবে আপনাকে নিজের অভ্যন্তরের সমস্ত কিছু ব্যবহার করতে $(wildcard)এবং তৈরি $(subst ...)করতে make(ফাইলের নামে কোনও অদ্ভুত অক্ষর "সমস্যাগুলি এড়ানো) করতে সক্ষম করুন। ( shমেকফাইলগুলির রেসিপি অংশ সহ স্ক্রিপ্টগুলিতে, find ... -print0 | xargs -0ফাঁকা, নতুনলাইনগুলি, নিয়ন্ত্রণের অক্ষরগুলি ইত্যাদির উপর ট্রিপিং এড়ানোর জন্য অন্য একটি পদ্ধতি ব্যবহার করা উচিত))


1 জিএনইউ ডকুমেন্টেশন নোট তৈরি করে আরও জানায় যে ::=২০১২ সালে পসিক্স অতিরিক্ত কাজ করে । আমি এর জন্য কোনও পসিক্স ডকুমেন্টের তাত্ক্ষণিক রেফারেন্স লিঙ্কটি খুঁজে পাইনি এবং আমি জানি না যে অফ-হ্যান্ড যা makeরূপগুলি সমর্থন করে ::=, যদিও জিএনইউ আজ তা করে, যেমন :=অ্যাসাইনমেন্টটি এখনই প্রসারিত করে।

দ্রষ্টব্য যেটি আমি জানি যতদূর জানি সমস্ত আধুনিক জিএনইউ এবং বিএসডি ভেরিয়েন্ট সহ বেশ কয়েকটি বৈকল্পিকগুলিতেও VAR := $(shell command args...)বানান করা যেতে পারে । এই অন্যান্য রূপগুলি যেমন ব্যবহার না করা হয় তেমনি সংক্ষিপ্ত হওয়া এবং আরও বেশি ভেরিয়েন্টে কাজ করা উভয় ক্ষেত্রেই উন্নত ।VAR != command args...make$(shell)VAR != command args...


ধন্যবাদ আমি (বিস্তারিত কমান্ড ব্যবহার করতে চান lsসঙ্গে sed, উদাহরণস্বরূপ কাটা) এবং তারপর rsync এবং অন্যান্য কমান্ড ফলাফল ব্যবহার করুন। আমাকে কি বার বার দীর্ঘ কমান্ডটি পুনরাবৃত্তি করতে হবে? আমি ফলাফলগুলি কোনও অভ্যন্তরীণ মেক ভেরিয়েবলের মধ্যে সঞ্চয় করতে পারি না?
আদম মতান

4
জিনু মেক করার একটি উপায় থাকতে পারে তবে আমি এটি কখনও ব্যবহার করি নি এবং আমরা যে সমস্ত মারাত্মক জটিল মেকফাইলগুলি ব্যবহার করি কেবল শেল ভেরিয়েবল এবং দৈত্য ওয়ান-লাইনার শেল কমান্ডগুলি প্রতিটি লাইনের শেষে "; \" দিয়ে নির্মিত হিসাবে ব্যবহার করি প্রয়োজন। (এখানে ব্যাকস্ল্যাশ সিকোয়েন্সের সাথে কাজ করতে কোড এনকোডিংটি পাওয়া যায় না,
হুঁ

4
সম্ভবত এর মতো কিছু: FILE = $(shell ls *.c | sed -e "s^fun^bun^g")
উইলিয়াম মরিস

4
@William: makeতা করতে পারে শেল ব্যবহার না করেই: FILE = $(subst fun,bun,$(wildcard *.c))
আইডেলিক

4
আমি উল্লেখ করতে চাই যে এই ক্ষেত্রে এটি খুব গুরুত্বপূর্ণ বলে মনে হচ্ছে না, আপনি স্বয়ংক্রিয়ভাবে ls এর আউটপুট পার্স করা উচিত নয়। ls এর অর্থ মানুষের কাছে তথ্য প্রদর্শন করা, স্ক্রিপ্টগুলিতে বেঁধে রাখা নয়। এখানে আরও তথ্য: mywiki.wooledge.org/ParsingLs সম্ভবত, যদি 'মেক' আপনাকে ওয়াইল্ডকার্ড সম্প্রসারণের প্রস্তাব দেয় না, "সন্ধান" "এলএস" এর চেয়ে ভাল।
রাউল সালিনাস-মন্টেইগুডো

53

এছাড়াও, টেরকের উত্তর ছাড়াও: একটি জিনিস যেটি দাঁড়িয়েছে তা হ'ল আপনি অলস-মূল্যায়িত ম্যাক্রো অ্যাসাইনমেন্ট ব্যবহার করছেন।

আপনি যদি জিএনইউ মেক এ থাকেন তবে :=পরিবর্তে অ্যাসাইনমেন্টটি ব্যবহার করুন =। এই কার্যভারটি ডান হাতের তত্ক্ষণাত তত্ক্ষণাত প্রসারিত হতে পারে এবং বাম হাতের ভেরিয়েবলে সংরক্ষণ করা হয়।

FILES := $(shell ...)  # expand now; FILES is now the result of $(shell ...)

FILES = $(shell ...)   # expand later: FILES holds the syntax $(shell ...)

আপনি যদি =অ্যাসাইনমেন্টটি ব্যবহার করেন তবে এর অর্থ হ'ল প্রতিটি একক ঘটনা সিনট্যাক্সটি $(FILES)প্রসারিত করবে $(shell ...)এবং শেল কমান্ডটি প্রেরণ করবে। এটি আপনার মেকিং জবকে ধীর করে দেবে বা এর কিছু আশ্চর্যজনক পরিণতি ঘটবে।


4
এখন যে আমাদের কাছে তালিকা রয়েছে আমরা কীভাবে তালিকার প্রতিটি আইটেমটি পুনরুক্তি করব এবং এটিতে একটি কমান্ড কার্যকর করব? যেমন বিল্ড বা পরীক্ষা?
anon58192932

4
@ anon58192932 নির্দিষ্ট পুনরাবৃত্তির, কমান্ড চালানো, সাধারণত একটি বিল্ড রেসিপি একটি শেল সিনট্যাক্স টুকরা এ, সম্পন্ন করা হয় তাই বরং এটা করতে চেয়ে শেল ঘটে: for x in $(FILES); do command $$x; done। দ্বিগুণ হয়ে গেছে $$যা $শেল থেকে একটি একক পাস নোট করুন । এছাড়াও, শেল টুকরা এক-লাইনার; মাল্টি-লাইন শেল কোডটি লিখতে, আপনি ব্যাকস্ল্যাশ ধারাবাহিকতা ব্যবহার করেন যা makeনিজে থেকেই প্রক্রিয়া করা হয় এবং এক লাইনে ভাঁজ করা হয়। যার অর্থ শেল-কমান্ড-পৃথককারী সেমিকোলনগুলি বাধ্যতামূলক।
কাজ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.