মেকফাইলে আমি কীভাবে সিডি কমান্ড লিখব?


354

উদাহরণস্বরূপ, আমার মেকফাইলে আমার কাছে এরকম কিছু রয়েছে:

all:
     cd some_directory

তবে আমি টাইপ makeকরার সময় echoকমান্ডের মতো কেবল 'সিডি কিছু_ ডিরেক্টরি' দেখতে পেলাম ।


5
আপনি কী করতে চান তা অস্পষ্ট, তবে আমার অভিজ্ঞতায় makeআমি কখনই ডিরেক্টরিটি পরিবর্তন করতে চাইনি। আপনার সমাধানের জন্য অন্য পদ্ধতির চেষ্টা করা উচিত?
পি 17

2
আপনার ডিরেক্টরিটি গুরুত্বপূর্ণ বলে বিশ্বাস করা একটি সাধারণ নবাগত ভুল। বেশিরভাগ জিনিসের জন্য এটি হয় না; cd dir; cmd fileপ্রায় সবসময় আরও কার্যকরভাবে হিসাবে প্রকাশ করা যেতে পারে cmd dir/file
ট্রিপলি

34
আপনার বর্তমান কাজের ডিরেক্টরিটি অসম্পূর্ণ, এটি বিশ্বাস করা একটি সাধারণ নবাগত ভুল। অনেক প্রোগ্রাম, বিশেষত শেল স্ক্রিপ্টগুলি একটি নির্দিষ্ট মানকে মাথায় রেখে লেখা হয় .। এটি সত্য যে বেশিরভাগ সরঞ্জামগুলি এমনভাবে ডিজাইন করা হয়েছে যাতে এর জন্য আপনার পিডাব্লুডিকে পরিবর্তন করার দরকার নেই। তবে এটি সর্বদা সত্য নয় এবং আমি মনে করি না যে এটি আপনার ডিরেক্টরি গুরুত্বপূর্ণ বলে বিশ্বাস করতে এটি "ভুল" বলা ভাল ধারণা।
এভলিন কোকেমুর

টিপ: আপনার cd কমান্ড "কোন ধরনের ফাইল অথবা ডাইরেক্টরি" বলে, এমনকি যখন (আপেক্ষিক) ডিরেক্টরির যদি না বিদ্যমান, পরীক্ষা করুন যে আপনার CDPATH এনভায়রনমেন্ট ভেরিয়েবল পারেন হয় খালি করুন অথবা অন্তর্ভুক্ত "।"। "Sh" দিয়ে কার্যনির্বাহিত আদেশগুলি তৈরি করুন, এটি সেট করা থাকলে কেবল সিডিপ্যাথের মাধ্যমে কোনও আপেক্ষিক পথ খুঁজে পাবে। এটি ব্যাশের সাথে বিপরীতে রয়েছে, যা চেষ্টা করবে। CDPATH পরামর্শের আগে।
ডেনিস হাও

উত্তর:


620

এটি প্রকৃতপক্ষে কমান্ডটি সম্পাদন করছে, ডিরেক্টরিটি ডিরেক্টরিতে পরিবর্তিত করছে some_directory, তবে এটি একটি উপ-প্রক্রিয়া শেল-এ সঞ্চালিত হয় এবং আপনি যে শেলটি থেকে কাজ করছেন তা কোনওটিই তৈরি করে না বা শেলকেও প্রভাবিত করে না।

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

উদাহরণ স্বরূপ:

all:
        cd some_dir; echo "I'm in some_dir"; \
          gcc -Wall -o myTest myTest.c

আপনি একটি ব্যাকস্ল্যাশ এবং একটি নতুন লাইন যুক্ত করলেও প্রতিটি কমান্ডের মধ্যে সেমিকোলন প্রয়োজনীয় necessary এটি পুরো স্ট্রিংটি শেল দ্বারা একটি একক লাইন হিসাবে পার্স করা হয় এর কারণে এটি। মন্তব্যে উল্লিখিত হিসাবে, আপনার কমান্ডগুলিতে যোগ দিতে '&&' ব্যবহার করা উচিত, যার অর্থ পূর্ববর্তী কমান্ডটি সফল হলে তারা কেবলমাত্র মৃত্যুদন্ড কার্যকর করতে পারেন।

all:
        cd some_dir && echo "I'm in some_dir" && \
          gcc -Wall -o myTest myTest.c

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

একটি সাধারণ ব্যবহার হ'ল সাব ডিরেক্টরিতে মেক কল করা, যা আপনি সন্ধান করতে চাইতে পারেন। এর জন্য একটি কমান্ড লাইন বিকল্প রয়েছে যাতে আপনাকে cdনিজেকে কল করতে হবে না , তাই আপনার নিয়মটি এ জাতীয় দেখাচ্ছে

all:
        $(MAKE) -C some_dir all

যা পরিবর্তিত হবে some_dirএবং Makefileলক্ষ্যটিকে "সমস্ত" দিয়ে সেখানে এটিকে সম্পাদন করবে । সেরা অনুশীলন হিসাবে, সরাসরি $(MAKE)কল করার পরিবর্তে ব্যবহার করুন make, কারণ ডান মেক দৃষ্টান্তটি কল করতে যত্ন নেওয়া হবে (যদি আপনি উদাহরণস্বরূপ, আপনার বিল্ড পরিবেশের জন্য একটি বিশেষ মেক সংস্করণ ব্যবহার করেন), পাশাপাশি চলমান অবস্থায় কিছুটা আলাদা আচরণ প্রদান করুন নির্দিষ্ট সুইচ ব্যবহার করে যেমন -t

রেকর্ডের জন্য, সর্বদা কমান্ডটি এটি সম্পাদন করে নিন (এটি স্পষ্টভাবে চাপা না দেওয়া পর্যন্ত), যদি এর কোনও আউটপুট না থাকে, যা আপনি দেখছেন।


8
ভাল, সবসময় না । প্রতিধ্বনিকে দমন করতে, লাইনের শুরুতে @ টিপুন।
বিটা

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

46
দুটি নিট: ১. কমান্ডগুলি সত্যই যুক্ত হওয়া উচিত &&কারণ ;ডিরেক্টরিটি উপস্থিত না থাকলে এবং cdব্যর্থ হলে শেলটি বর্তমান ডিরেক্টরিতে থাকা অবশিষ্ট কমান্ডগুলি চালিয়ে রাখবে, যা রহস্যজনক "ফাইলের মতো জিনিসগুলির কারণ হতে পারে সংকলনের জন্য বার্তাগুলি, মেকিং করার সময় অসীম লুপগুলি বা এই জাতীয় বিধিগুলির জন্য বিপর্যয় clean:: cd dir; rm -rf *। ২. সাব-মেকগুলি করার সময়, $(MAKE)পরিবর্তে কল করুনmake যাতে বিকল্পগুলি সঠিকভাবে পাস হবে
অ্যান্ড্রুডটন

2
@ স্পিরিয়াল, আমি সাধারণত একটি প্যাটার্ন রুলটি সংজ্ঞায়িত করি: %-recursive:শরীরের সাথে: @T="$@";$(MAKE) -C some_dir $${T%-*}(আমার সাধারণত একটি লুপও থাকে, সাবডিয়ারের তালিকার উপরে লুপ করা, এটি $${T%-*}একটি বাশ প্রসার যা -recursiveলক্ষ্য নামের অংশটি সরিয়ে দেয় ) এবং তারপরে প্রত্যেকের জন্য স্পষ্ট সংক্ষিপ্ত সরাসরি (এবং .PHONY) লক্ষ্যমাত্রা নির্ধারণ করুন, মত all: all-recursive, check: check-recursive, clean: clean-recursive
ফলস্ট্রো


94

জিএনইউ থেকে শুরু করে 82.২২ (জুলাই ২০১০) তৈরি করে, আপনি .ONESHELLশেলটির একক ইনস্ট্যান্টিশনে সমস্ত রেসিপি লাইন চালানোর জন্য বিশেষ লক্ষ্য ব্যবহার করতে পারেন (সাহসী জোরের খনি):

  • নতুন বিশেষ লক্ষ্য: .ONESHELLনির্দেশ করে করতে ডাকা শেল একটি একক উদাহরণস্বরূপ এবং এটি প্রদান সমগ্র রেসিপি নির্বিশেষে কিভাবে এটি অনেক লাইন ধারণ করে। [...]
.ONESHELL: # Only applies to all target
all:
    cd ~/some_dir
    pwd # Prints ~/some_dir if cd succeeded

6
শুধু লক্ষ করুন যে, pwdনিজেই সেইসাথে কাজ করে, `pwd`(ব্যাকটিক সঙ্গে), কিন্তু $(shell pwd)$(PWD)এখনো কাজ করার আগে ডিরেক্টরি ফিরে আসবে cdকমান্ড, তাই আপনি সরাসরি তাদের ব্যবহার করতে পারবেন না।
anol

3
হ্যাঁ কারণ ভেরিয়েবল এবং ফাংশন সম্প্রসারণ মেক দ্বারা কমান্ডগুলি কার্যকর করার আগে সম্পন্ন করা হয়, pwdএবং `pwd`এটি নিজেই শেল দ্বারা সম্পাদিত হয়।
চনোসোস

2
প্রত্যেকে লিগ্যাসি মেকফিলগুলিতে কাজ করে না এবং তারপরেও এই উত্তরটি সম্ভবত এই সম্ভাবনাটি জানা সম্পর্কে about
Chnossos

1
এটি একটি বিরক্তিকর / বিপজ্জনক বিকল্প হতে পারে কারণ কেবলমাত্র একটি লক্ষ্যের জন্য শেষ কমান্ডটি ব্যর্থতার কারণ হতে পারে (কোনও পূর্ববর্তী কমান্ড ব্যর্থতা উপেক্ষা করা হবে) এবং সম্ভবত আপনার সাথে কাজ করা কেউই এটির প্রত্যাশা করবেন না।
তোবিআই

1
সেট SHELLFLAGSকরুন -e -cএবং শেলটি ব্যর্থ হওয়া প্রথম কমান্ডে প্রস্থান করবে।
টিমোথি বাল্ডউইন

21

ডিরেক্টরিগুলি পরিচালনা করতে এবং তৈরি করার জন্য এখানে একটি সুন্দর কৌশল। মাল্টলাইন স্ট্রিং, বা "সিডি" ব্যবহার করার পরিবর্তে প্রতিটি কমান্ডে, একটি সাধারণ chdir ফাংশনটি এরূপ হিসাবে সংজ্ঞায়িত করুন:

CHDIR_SHELL := $(SHELL)
define chdir
   $(eval _D=$(firstword $(1) $(@D)))
   $(info $(MAKE): cd $(_D)) $(eval SHELL = cd $(_D); $(CHDIR_SHELL))
endef

তারপরে আপনাকে যা করতে হবে তা হ'ল এটিকে আপনার নিয়মে কল করুন:

all:
          $(call chdir,some_dir)
          echo "I'm now always in some_dir"
          gcc -Wall -o myTest myTest.c

আপনি নিম্নলিখিতগুলি করতে পারেন:

some_dir/myTest:
          $(call chdir)
          echo "I'm now always in some_dir"
          gcc -Wall -o myTest myTest.c

41
"বুদ্ধিমান"? নিজেকে পায়ে গুলি করার মতো পর্যাপ্ত দড়ি More
ট্রিপলি

1
এই বর্তমান ডিরেক্টরিটি কি কেবল সেই নিয়মে কমান্ডের জন্য সেট করা আছে, বা পরবর্তীকালে সম্পাদিত সমস্ত নিয়মের জন্য? এছাড়াও, উইন্ডোজ অধীনে এই কাজ কিছু প্রকরণ হতে পারে?
ব্যবহারকারী 117529

8
এটি অবশ্যই সমান্তরাল সম্পাদনের জন্য বিরতি দেয় ( -jn), যা সত্যই তৈরি করার পুরো বিষয়টি point
বোবোগো

5
এটি একটি খারাপ হ্যাক। আপনার যদি কখনও এ জাতীয় জিনিসটি অবলম্বন করতে হয় তবে আপনি মেকফাইলগুলি তার জন্য ব্যবহার করছেন না।
gatopeich

4
আমি নিশ্চিত যে এটি একটি খারাপ হ্যাক নিশ্চিত না। তবে আপনি করতে পারেন এমন কিছু দুষ্ট কাজকে প্রদর্শন করে।
জোস

9

এটি একবার পেলে এটি কী করতে চান? প্রতিটি কমান্ড একটি সাব-শেলের মধ্যে কার্যকর করা হয়, সুতরাং সাব-শেল ডিরেক্টরি পরিবর্তন করে, তবে শেষ ফলাফলটি হ'ল পরবর্তী কমান্ডটি এখনও বর্তমান ডিরেক্টরিতে রয়েছে।

জিএনইউ মেক দিয়ে আপনি এমন কিছু করতে পারেন:

BIN=/bin
foo:
    $(shell cd $(BIN); ls)

5
কেন $(shell ...)যখন cd $(BIN); lsবা cd $(BIN) && ls(যেমন @andrewdotn নির্দিষ্ট) যথেষ্ট হবে।
ওয়াপেস

1

দির পরিবর্তন করতে

foo: 
    $(MAKE) -C mydir

multi:
    $(MAKE) -C / -C my-custom-dir   ## Equivalent to /my-custom-dir

-6

এটার মত:

target:
    $(shell cd ....); \
    # ... commands execution in this directory
    # ... no need to go back (using "cd -" or so)
    # ... next target will be automatically in prev dir

শুভকামনা!


1
না, এটা ভুল। বিশেষত, $(shell cd ....)যখন মেকফিল শুরুতে পার্স করা হয় তখন এইটিকে কার্যকর করা হয়, যখন এই নির্দিষ্ট রেসিপিটি চালানো হয় না।
ট্রিপলি

@triplee বেশ নেই - $(shell)প্রসারিত হয় শুধুমাত্র যখন করতে বিল্ড করার সিদ্ধান্ত নেয় লক্ষ্য । যদি করতে রেসিপি দরকার না, এটা এটি প্রসারিত করা হবে না।
বোবোগো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.