সোর্স lib / * কাজ করে না কেন?


11

আমার একটি ছোট প্রোগ্রাম রয়েছে যাতে নিম্নলিখিত ফোল্ডারটির কাঠামো রয়েছে:

- main.sh
- lib/
  - clean.sh
  - get.sh
  - index.sh
  - test.sh

প্রতিটি ফাইলের মধ্যে একটি একক ফাংশন থাকে যা আমি ব্যবহার করি main.sh

main.sh:

source lib/*

get_products
clean_products
make_index
test_index

উপরের দিকে প্রথম দুটি ফাংশন কাজ করে তবে দ্বিতীয় দুটি কাজ করে না।

তবুও যদি আমি এর সাথে প্রতিস্থাপন করি source lib/*:

source lib/get.sh
source lib/clean.sh
source lib/index.sh
source lib/test.sh

প্রত্যাশা অনুযায়ী সবকিছুই কাজ করে।

কেউ জানেন কেন source lib/*প্রত্যাশার মতো কাজ করে না?


2
প্রশ্নের উত্তর না দিয়ে, যদি আপনি এটি ওয়ান-লাইনারে করতে চান তবে দেখুন /etc/bashrcএটি কীভাবে forলুপ ব্যবহার করে /etc/profile.d/*.sh। আপনি বিশ্বাস করেন বিষয়বস্তু তাহলে lib/এটি একটি এক-লাইনের কমে যাবে:for i in lib/*.sh; do . "$i"; done
রিচ

উত্তর:


21

বাশের sourceবিল্টিনটি কেবল একটি একক ফাইলের নাম নেয়:

source filename [arguments]

প্রথম প্যারামিটারের বাইরে যে কোনও কিছুতে অবস্থানগত প্যারামিটার হয়ে যায় filename

একটি সাধারণ চিত্র:

$ cat myfile
echo "param1: $1"
$ source myfile foo
param1: foo

এর সম্পূর্ণ আউটপুট help source

source: source filename [arguments]

Execute commands from a file in the current shell.

Read and execute commands from FILENAME in the current shell.  The
entries in $PATH are used to find the directory containing FILENAME.
If any ARGUMENTS are supplied, they become the positional parameters
when FILENAME is executed.

Exit Status:
Returns the status of the last command executed in FILENAME; fails if
FILENAME cannot be read.

(এটি সমতুল্য "ডট উত্স" অন্তর্নির্মিত ক্ষেত্রেও প্রযোজ্য .যা এটি লক্ষণীয়, এটি পসিক্স উপায় এবং এভাবে আরও বহনযোগ্য able)

আপাতদৃষ্টিতে পরস্পরবিরোধী আচরণ হিসাবে আপনি দেখতে পাচ্ছেন যে আপনি কাজ করার পরে মেইন.শ চালানোর চেষ্টা করতে পারেন set -x। কি বিবৃতি কার্যকর করা হচ্ছে এবং কখন একটি ক্লু সরবরাহ করতে পারে তা দেখে।


7

বাশ ডকুমেন্টেশন ইঙ্গিত দেয় যে sourceএকটি একক ফাইলের উপর কাজ করে :

। (একটি পিরিয়ড)

ফাইলের নাম [যুক্তি]

বর্তমান শেল প্রসঙ্গে ফাইলের যুক্তি থেকে কমান্ডগুলি পড়ুন এবং সম্পাদন করুন । যদি ফাইলের নাম ...

এবং উত্স কোড ... উত্সের জন্য ... এটির ব্যাক আপ করে:

result = source_file (filename, (list && list->next));

কল করতে source_fileসংজ্ঞায়িত কোথায় :evalfile.c_evalfile

rval = _evalfile (filename, flags);

এবং _evalfileকেবল একটি একক ফাইল খোলে:

fd = open (filename, O_RDONLY);

5

বি-স্তরের দরকারী উত্তরের পরিপূরক করা , আমি পরামর্শ দিচ্ছি যে প্রকারের প্রসারণের চেষ্টা করা ফাইলগুলি যদি সেখানে থাকে তবে আপনি যদি অনিশ্চিত হন তবে লোভী গ্লোব সম্প্রসারণ কখনই ব্যবহার করবেন না।

আপনি যখন নীচে এটি করেছিলেন তখন .shকোনও ক্ষতিকারক কমান্ড (উদাহরণস্বরূপ rm -rf *) কেবলমাত্র একটি অস্থায়ী ফাইলের ( এক্সটেনশন না থাকা ) ফাইলের সম্ভাবনা থাকে যা কার্যকর করা যেতে পারে (ধরে নিলে তারা অনুমতি গ্রহণ করেছে)

source lib/*

সুতরাং সর্বদা যথাযথ বাউন্ড সেট সহ গ্লোব সম্প্রসারণ করুন, যদিও আপনি *.shকেবল ফাইলগুলিতে লুপ করতে পারতেন

for globFile in lib/*.sh; do
    [ -f "$globFile" ] || continue
    source "$globFile"
done

এখানে [ -f "$globFile" ] || continueযত্ন লুপের ফিরে গ্রহণ করা যদি কোনো উল্লিখিত glob প্যাটার্ন বর্তমান ফোল্ডার অর্থাত বর্ধিত শেল অপশনের সমতুল্য মিল হবে nullglobমধ্যে bashশেল।


প্রক্রিয়া প্রতিস্থাপনের সাথে catএটি ব্যবহার করেও কাজ করবে:source <(cat lib/*.sh)
Xophmeister

@ এক্সফমিস্টার, ... "কাজের" জন্য আরও সীমাবদ্ধ মানের জন্য। আপনার সাথে ডিবাগ করার চেষ্টা যদি set -xএকটি PS4রাখে যে BASH_SOURCEএবং LINENOআপনার লগ, আপনি আর যা ফাইল দেখতে এবং লাইন একটি প্রদত্ত কমান্ড থেকে আসে পারে।
চার্লস ডাফি

2
@ এক্সফমিস্টার, ... এছাড়াও, একটি স্ক্রিপ্ট এটির প্রয়োগের সাথে শর্ট সার্কিট করতে পারে return। এই অনুশীলন অনুসরণ করে, যে কোনও স্ক্রিপ্ট এটি করছে যা নিম্নলিখিত সকলকে কার্যকর করতে বাধা দেয়
চার্লস ডাফি 15

1
/etc/bashrcএটি প্রক্রিয়াজাতকরণের সময় এটি কীভাবে সম্পন্ন হয় তার খুব কাছাকাছি /etc/profile.d/*.sh
ধনী

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