কেন আমার প্রোগ্রামটিকে "সেট" বলা হচ্ছে তা কার্যকর করা হচ্ছে না?


10

আমি এর মতো একটি সাধারণ সি প্রোগ্রাম তৈরি করেছি:

int main(int argc, char *argv[]) {

    if (argc != 5) {
       fputs("Not enough arguments!\n", stderr);
       exit(EXIT_FAILURE);
    }

এবং আমি আমার PATH এ জাতীয় / bash.bashrc এ পরিবর্তন করেছি:

PATH=.:$PATH

আমি এই প্রোগ্রামটিকে set.c হিসাবে সংরক্ষণ করেছি এবং এটি সংকলন করছি

gcc -o set set.c

ফোল্ডারে

~/Programming/so

যাইহোক, আমি কল যখন

set 2 3

কিছুই ঘটেনি. উপস্থিত কোনও পাঠ্য নেই।

কল করা হচ্ছে

./set 2 3

প্রত্যাশিত ফলাফল দেয়

PATH এর আগে ও আগে কখনও আমার সমস্যা হয়নি

which set

আয় ./set। সুতরাং দেখে মনে হচ্ছে যে পথটি সঠিক। কি হচ্ছে?


10
এটি যুক্ত করা তুলনামূলকভাবে বিপজ্জনক। ' আপনার পথের দিকে স্থানীয় ডিরেক্টরি থেকে কোনও কিছু কার্যকর করার সময়। / ব্যবহার করা ভাল, বা এক্সিকিউটিভকে ~ / bin /
TREE

7
testমূলত একই কারণে আপনার পরীক্ষা প্রোগ্রামটি কল করাও একটি খারাপ ধারণা ; testএটিও অন্তর্নির্মিত একটি শেল।
জোনাথন লেফলার

@ জোনাথনলফলার এবং তবুও দ্রুত প্রোগ্রামের জন্য পরীক্ষা testদেওয়ার জন্য এটি বোধগম্য হয়। অবশ্যই আপনি এটি নিজের মধ্যে রাখার সময় PATHপর্যন্ত আপনার সত্যই আলাদা নামটি নিয়ে আসা উচিত ছিল। এবং যতক্ষণ না আপনি প্রোগ্রামটি নিজের মধ্যে রাখেন ততক্ষণ আপনাকে PATHএটিকে ./testযেভাবেই ডাকা উচিত । সুতরাং testকোনও প্রোগ্রামের জন্য নামটি ব্যবহার করা যতক্ষণ না এটি একটি তাত্ক্ষণিক পরীক্ষা যা দিন শেষ হওয়ার আগেই আপনি মুছতে চান তা ঠিক।
ক্যাস্পারড

1
@ ক্যাস্পার্ড: যতদূর আমি সচেতন, দ্রুত পরীক্ষা প্রোগ্রামের প্রচলিত নাম foo
এইচএমখোলম

আপনি যদি নামটি দিয়ে থাকেন lsতবে যখনই আপনি দেখতে যান এটি বিদ্যমান কিনা এটি চলবে (তবে কেবল আপনি যদি প্রশ্নটিতে যেমন করেন তবে আপনার পথটি পরিবর্তন করেন)।
ctrl-alt-delor

উত্তর:


24

ব্যবহারের পরিবর্তে which, যা আপনার সবচেয়ে বেশি প্রয়োজন হলে কাজ করে না , typeআপনি যখন কোনও কমান্ড টাইপ করবেন তখন কী চলবে তা নির্ধারণ করতে ব্যবহার করুন :

$ which set
./set
$ type set
set is a shell builtin

শেলটি সর্বদা অনুসন্ধানের আগে অন্তর্নির্মিত সন্ধান করে $PATH, তাই সেটিংস $PATHএখানে সহায়তা করে না।

এটা তোলে অন্য কিছু করার জন্য আপনার এক্সিকিউটেবল নামান্তর করতে সেরা হতে পারে, কিন্তু আপনার কাজ নামে প্রোগ্রাম প্রয়োজন হলে set, আপনি একটি শেল ফাংশন ব্যবহার করতে পারেন:

$ function set { ./set; }
$ type set
set is a function
set ()
{
    ./set
}

(এটি এতে কাজ করে bashতবে অন্যান্য শেলগুলি kshএটির অনুমতি নাও দেয় a আরও বহনযোগ্য সমাধানের জন্য মাইকজার্জের উত্তর দেখুন))

এখন টাইপিং set"সেট" নামক ফাংশনটি চালাবে যা কার্যকর করে ./set। জিএনইউ bashবিল্টিনগুলি সন্ধান করার আগে ফাংশন সন্ধান করে এবং এটি অনুসন্ধানের আগে বিল্টিনগুলির সন্ধান করে $PATH। ব্যাশ ম্যান পৃষ্ঠায় "কম্যান্ড এক্সিকিউশন" নামের বিভাগটি এ সম্পর্কে আরও তথ্য দেয়।

আরও দেখুন উপর ডকুমেন্টেশন builtinএবং command: help builtinএবং help command


3
আপনাকে সুপারিশ typeউপর which, কিন্তু কোনো কারণে দেবেন না। ( আমি জানি কেন , তবে যার সুপারিশের প্রয়োজন কেউ তা করেনি))
সিজেএম

1
@ সিজেএম কেন তা নয় তার পুরো গ্রন্থটি এখানে : unix.stackexchange.com/questions/85249/…
অ্যান্টনি

খুবই তথ্যবহুল. আপনি কখনই অনুমান করতে পারবেন না যে এমন একটি আপাতদৃষ্টিতে সহজ কমান্ডটি নিয়ে একটি এত সহজ বিতর্ক আছে যা একটি সাধারণ কাজ করে
গণিয়া ড্যান আন্দ্রেই

4
@ গ্যানিয়াডানআন্দ্রেই মূলত, এর typeপরিবর্তে ব্যবহার করুন which, আপনার প্রোগ্রামটির নাম "সেট" রাখবেন না এবং বুঝতে পারেন যে function set { ./set; }এটি একটি কুশ্রী হ্যাক যা সম্ভবত আপনার এড়ানো উচিত।
হলুদন্তফিল

11

setবাশের একটি অন্তর্নির্মিত (এবং সম্ভবত বেশিরভাগ অন্যান্য শাঁস)। এর অর্থ হল যে ফাংশনটি সন্ধান করার সময় বাশ এমনকি পথ অনুসন্ধান করবে না।

পার্শ্ববর্তী মন্তব্য হিসাবে, আমি .সুরক্ষার কারণে এই পথে যুক্ত করার বিরুদ্ধে দৃ strongly়ভাবে পরামর্শ দেব । উদাহরণস্বরূপ cd, /tmpঅন্য কোনও ব্যবহারকারীর একটি এক্সিকিউটেবল ফাইল যুক্ত করার পরে আইনের বাইরে বেরোনোর উদাহরণটি কল্পনা করুন /tmp/cd


2
হ্যাঁ, এটি একটি মূর্খ ধারণা যা আমার শিক্ষক আমাদের উপর চাপিয়ে দিয়েছিলেন, "কোনও প্রোগ্রাম উপস্থাপন করার সময় অলাভজনক দেখবেন না" done এটি সম্পন্ন না হলে তিনি আপনাকে গ্রেড করেছেন
গ্যানিয়া ড্যান আন্দ্রেই

1
দুর্দান্ত শিক্ষকদের জন্য ব্রাউনি পয়েন্টগুলি :(
klimpergeist

4
cdঅন্তর্নির্মিত একটি শেল, সুতরাং উদাহরণটি একই কারণে কাজ করবে না set
এমিল জ্যাবেক

15
ব্যবহার ./fooএকটি প্রোগ্রাম ডাকা হয় পেশাদারী; এটি দেখায় যে কেন .আপনি $ PATH এ থাকবেন না তা আপনি বুঝতে পেরেছেন । আপনার শিক্ষক ভুল, এবং আপনি তাকে বলতে পারেন আমি তাই বলেছি।
zwol

10

setএটি কেবল একটি বিল্টিন নয়, এটি একটি পসিক্স বিশেষ অন্তর্নির্মিত । কয়েক builtin কমান্ড যা মান-নির্দিষ্ট অন্য কিছু করার আগে কমান্ড অনুসন্ধান পাওয়া যাবে হয় আছে - $PATHঅনুসন্ধান করা হয় না, ফাংশন নাম অনুসন্ধান করা হয়, এবং ইত্যাদি সর্বাধিক builtins যা হয় না বিশেষ আসলে প্রয়োজনীয় POSIX মান দ্বারা হতে শেলটির নিজস্ব বিল্টিন পদ্ধতি চালিয়ে $PATH যাওয়ার আগে এটিতে খুঁজে পাওয়া যায় । এই সত্য echoএবং সবচেয়ে অন্যদের (যদিও মান এ ব্যাপারে সম্মানিত করা হয় গত খোলা গ্রুপ মেইলিং তালিকা এ বিবাদের একটি ব্যাপার হয়েছে কিনা) , কিন্তু না এর set, trap, break,return, continue, ., :, times, eval, exit, export, readonly, unset, অথবা exec

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

যাইহোক, আপনি যদি এটি আক্রমণ করার ইচ্ছা করেন তবে আপনি এটি দিয়ে বহনযোগ্যভাবে করতে পারেন alias। শেল সম্প্রসারণের ক্রমটি এই কর্মব্যবস্থাকে সক্ষম করে। কারণ aliasকমান্ডটি পড়ার সময় প্রসারিত হয়, আপনি setআপনার সংজ্ঞায় নামটি প্রতিস্থাপন করুন যা সঠিকভাবে প্রসারিত হবে, এটি সম্ভবত সেই নামের একটিতে প্রসারিত হওয়া উচিত নয়।

সুতরাং আপনি করতে পারেন:

alias set=./set

... যা ঠিক কাজ করবে।


3

সমস্যাটি হ'ল এটি setএকটি শেল বিল্টিন এবং সবচেয়ে কার্যকর সমাধানটি হ'ল আপনার এক্সিকিউটেবল প্রোগ্রামের জন্য আলাদা নাম ব্যবহার করা।

ঘটনাক্রমে, গত সপ্তাহে, আমি একই নামের শেল বিল্টিনগুলির পরিবর্তে সিস্টেম কমান্ডগুলি কীভাবে চালাতে হবে এবং আমি যে সমাধানটি স্বীকার করেছি তা হ'ল কমান্ডটি চালানো সম্পর্কে একটি প্রশ্ন জিজ্ঞাসা করেছি env:

env set 2 3

এই নির্দিষ্ট ক্ষেত্রে, আপনি ইতিমধ্যে জানেন যে আপনি যে কমান্ডটি ব্যবহার করতে চান তা আপনার বর্তমান ডিরেক্টরিতে অবস্থিত, সেখানে সরাসরি তার পথ প্রবেশ করে নির্বাহী চালানো ভাল ( .বর্তমান কার্যক্ষম ডিরেক্টরিটি উপস্থাপন করে):

./set 2 3

উপরের উভয় সমাধানগুলি শেল অজোনস্টিক, অর্থাত্, আপনি কোন শেল ব্যবহার করছেন তা নির্বিশেষে তারা কাজ করবে।

commandবিল্টিন ব্যবহারের মতো পরামর্শগুলি ব্যাশে কাজ করবে না: এটি কেবল শেল ফাংশনগুলি চালানো থেকে বাধা দেয় । যদিও এটি নথিভুক্ত করা হয়নি, আমি এটিও লক্ষ্য করেছি যে ব্যবহার করে commandশেল কীওয়ার্ডগুলিও দমন করে । যাইহোক, এটি শেল বিল্টিনগুলির মতো একই কাজ করবে না set। আমি যেমন এটি বুঝতে পারি, commandzsh এর মতো অন্যান্য শেলগুলির সাথে কাজ করতে পারে।

এছাড়াও, যেমন ঠাট \setবা "set"বা 'set'ব্যাশ builtins কাজ করে না - যদিও তারা এর পরিবর্তে এক্সিকিউটেবল ফাইলের চলমান জন্য দরকারী alias লেখা বা শেল কীওয়ার্ড

দ্রষ্টব্য: এই উত্তরটি মূলত এরিকের (গৃহীত) উত্তরের মন্তব্য হিসাবে শুরু হয়েছিল তবে একটি মন্তব্যে ফিট হয়ে উঠতে খুব বড় হয়েছে। PATH- র ব্যবহারের typeএবং যোগ না করার প্রস্তাব দেওয়া অন্য উত্তরগুলি .ভাল।

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