আমি কীভাবে মেকফিল লক্ষ্যগুলিতে ব্যাশ সিনট্যাক্স ব্যবহার করতে পারি?


208

আমি প্রায়ই খুঁজে ব্যাশ মত খুব সহায়ক, যেমন প্রক্রিয়া প্রতিকল্পন সিনট্যাক্স diff <(sort file1) <(sort file2)

মেকফাইলে কি এই জাতীয় বাশ কমান্ড ব্যবহার করা সম্ভব? আমি এরকম কিছু নিয়ে ভাবছি:

file-differences:
    diff <(sort file1) <(sort file2) > $@

আমার GNU Make 3.80 এ এটি একটি ত্রুটি দেয় কারণ এটি আদেশগুলি কার্যকর করার shellপরিবর্তে এটি ব্যবহার করে bash


এটি ঠিক আমার সমস্যা ছিল, এই প্রশ্নটি খুঁজতে আমাকে কমপক্ষে এক ঘন্টা সময় নিয়েছিলেন! আমি আমার ত্রুটি বার্তাটি এখানে রেখেছি যাতে ভবিষ্যতের পাঠকরা এটি খুঁজে পেতে পারেন: /bin/sh: -c: line 0: syntax error near unexpected token ('`
ডেভিড

উত্তর:


380

জিএনইউ মেক ডকুমেন্টেশন থেকে,

5.3.1 Choosing the Shell
------------------------

The program used as the shell is taken from the variable `SHELL'.  If
this variable is not set in your makefile, the program `/bin/sh' is
used as the shell.

সুতরাং SHELL := /bin/bashআপনার মেকফিলের শীর্ষে রাখুন, আপনার ভাল হওয়া উচিত।

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

all: a b

a:
    @echo "a is $$0"

b: SHELL:=/bin/bash   # HERE: this is setting the shell for b only
b:
    @echo "b is $$0"

এটি মুদ্রণ করবে:

a is /bin/sh
b is /bin/bash

আরও তথ্যের জন্য ডকুমেন্টেশনে "লক্ষ্য-নির্দিষ্ট পরিবর্তিত মানগুলি" দেখুন। এই লাইনটি মেকফিলের যে কোনও জায়গায় যেতে পারে, এটি টার্গেটের আগেই হওয়া উচিত নয়।


43
500 বন্টি থেকে কোটের জন্য অপেক্ষা করছে man। সময় সম্পর্কে কথা বলুন। : পি
সিদ্ধার্থআরটি

3
@ ইনলওয়েথ পিথন ভাল, infoআসলে, তবে, আমি অনুমান করি এটি সত্যিই অ্যান্ডিকে সাহায্য করেছে। আমি জানি আমার মতো দিনগুলি ছিল ...
ডার্বার্ট

3
যদি সন্দেহ হয় তবে @ ডারবার্টের আক্ষরিক অর্থ: মেকফিলের SHELL=/bin/bashপ্রথম লাইন হিসাবে (বা মন্তব্যের ঠিক পরে)।
ইয়াহেন ইয়াকিমোভিচ

1
ধন্যবাদ @derobert মধ্যে আমার সমস্যার সমাধান stackoverflow.com/questions/26806832/...
চন্দন চৌধুরী

2
কেবলমাত্র একটি নির্দিষ্ট টার্গেটের জন্য শেল ভেরিয়েবল পরিবর্তন করা কিন্তু অন্যকে বাছাই করা সম্ভব?
এন্ট্রিড

18

আপনি bashসরাসরি কল করতে পারেন, -cপতাকাটি ব্যবহার করতে পারেন :

bash -c "diff <(sort file1) <(sort file2) > $@"

অবশ্যই, আপনি ভেরিয়েবল to @ এ পুনঃনির্দেশ করতে সক্ষম নাও হতে পারেন, কিন্তু যখন আমি এটি করার চেষ্টা করেছি তখন আমি -bash: $@: ambiguous redirectএকটি ত্রুটি বার্তা হিসাবে পেয়েছি , সুতরাং আপনি এটির মধ্যে beforeোকার আগেই এটি সন্ধান করতে পারেন (যদিও আমি ব্যাশ ৩.২. কিছু ব্যবহার করে, তাই সম্ভবত আপনার অন্যরকমভাবে কাজ করে)।


4

পোর্টেবিলিটিটি গুরুত্বপূর্ণ হলে আপনি আপনার মেকফিলের একটি নির্দিষ্ট শেলের উপর নির্ভর করতে পারবেন না। সমস্ত পরিবেশে বাশ উপলব্ধ নেই।


4

আপনি ডিফল্ট শেলটি ব্যবহার না করে সরাসরি আপনার মেকফিলের মধ্যে ব্যাশ কল করতে পারেন:

bash -c "ls -al"

পরিবর্তে:

ls -al

1
নোট করুন যে makeপরিবেশের পরিবর্তনশীল শেলের মান উপেক্ষা করে।
চোরোবা

2

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

আপনি যদি sudo dpkg-reconfigure dashপ্রম্পটে চালান এবং 'না' উত্তর দেন তবে আপনার সিস্টেমটি ডিফল্ট শেল হিসাবে ড্যাশ ব্যবহার করবে না। এটি তখন বাশকে নির্দেশ করবে (কমপক্ষে উবুন্টুতে)। মনে রাখবেন যে আপনার সিস্টেম শেল হিসাবে ড্যাশ ব্যবহার করা যদিও কিছুটা দক্ষ।


1
নাম অনুসারে আহবান করা হলে sh, ব্যাশ সামঞ্জস্যতা মোডে চালিত হয় ( set -o posix)। ওপি যে কার্যকারিতাটি ব্যবহারের চেষ্টা করছে, বিকল্প প্রতিস্থাপন করছে তা এই মোডে উপলভ্য নয়।
চার্লস ডাফি

1

একটি উপায় যা কাজ করে তা হ'ল এটি আপনার টার্গেটের প্রথম লাইনে রাখে:

your-target: $(eval SHELL:=/bin/bash)
    @echo "here shell is $$0"
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.