"বিড়াল << ইওএফ" বাশে কীভাবে কাজ করে?


627

একটি প্রোগ্রামে ( psql) -তে মাল্টি-লাইন ইনপুট প্রবেশের জন্য আমার স্ক্রিপ্ট লিখতে হবে ।

কিছুটা গুগল করার পরে, আমি নিম্নলিখিত সিনট্যাক্সের কাজগুলি পেয়েছি:

cat << EOF | psql ---params
BEGIN;

`pg_dump ----something`

update table .... statement ...;

END;
EOF

এই সঠিকভাবে (থেকে বহু-লাইন স্ট্রিং নির্মান BEGIN;করতে END;এবং একটি ইনপুট যেমন পাইপ সহ) psql

তবে এটি কীভাবে / কেন কাজ করে আমার কোনও ধারণা নেই, কেউ দয়া করে ব্যাখ্যা করতে পারেন কি?

আমি প্রধানত উল্লেখ করছি cat << EOF, আমি >কোনও ফাইলের আউটপুট জানি, কোনও ফাইলে >>সংযোজন করি, <ফাইল থেকে ইনপুট পড়ি ।

কী <<ঠিক হবে?

এবং এর জন্য কোনও ম্যান পেজ আছে?


26
এটি সম্ভবত একটি অকেজো ব্যবহার cat। ব্যবহার করে দেখুন psql ... << EOF ... দেখুন "এখানে স্ট্রিং"। mywiki.wooledge.org/BashGuide/InputAndOutput?# এখানে পোস্ট করুন
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত

1
আমি অবাক হয়েছি এটি বিড়ালের সাথে কাজ করে তবে প্রতিধ্বনি দিয়ে নয়। বিড়ালের স্ট্যান্ডিন হিসাবে কোনও ফাইলের নাম আশা করা উচিত, চর স্ট্রিং নয়। পিএসকিএল << ইওএফ যৌক্তিক মনে হয় তবে অন্যভাবে নয়। বিড়ালের সাথে কাজ করে তবে প্রতিধ্বনি দিয়ে নয়। অদ্ভুত আচরণ সে সম্পর্কে কোন সূত্র?
অ্যালেক্স

আমার জবাব: প্যারামিটার ছাড়াই বিড়াল নির্বাহ করে এবং ইনপুট (স্টিডিন) এর মাধ্যমে যা কিছু প্রেরণ করে তা আউটপুটটিতে প্রতিলিপি করে, সুতরাং এর মাধ্যমে আউটপুটটি ফাইলটি পূরণ করে>। প্রকৃতপক্ষে প্যারামিটার হিসাবে পড়া একটি ফাইলের নাম স্টিন স্ট্রিম নয়।
অ্যালেক্স

@ অ্যালেক্স প্রতিধ্বনি কেবল catস্ট্যান্ডিং পড়ার সময় এটির কমান্ড লাইন আর্গুমেন্টগুলি মুদ্রণ করে (যখন এটির সাথে পাইপ করা হয়) বা একটি ফাইল পড়বে যা এর কমান্ড লাইন
আর্গগুলির সাথে সম্পর্কিত

উত্তর:


517

এটিকে স্টিডিনে স্ট্রিং সরবরাহ করতে হেরডোক ফর্ম্যাট বলা হয়। আরও তথ্যের জন্য https://en.wikedia.org/wiki/Here_docament#Unix_shells দেখুন ।


থেকে man bash:

এখানে নথি

এই ধরণের পুনর্নির্দেশটি শেলটিকে বর্তমান উত্স থেকে ইনপুট পড়ার নির্দেশ দেয় যতক্ষণ না কেবলমাত্র শব্দ (কোনও পেছনের ফাঁকা চিহ্ন সহ) একটি লাইন না দেখা পর্যন্ত।

সেই বিন্দু পর্যন্ত পঠিত সমস্ত লাইন তখন কমান্ডের জন্য স্ট্যান্ডার্ড ইনপুট হিসাবে ব্যবহৃত হয়।

এখানে-নথির বিন্যাসটি হ'ল:

          <<[-]word
                  here-document
          delimiter

কোনও পরামিতি সম্প্রসারণ, কমান্ড প্রতিস্থাপন, গাণিতিক সম্প্রসারণ, বা পথের নাম সম্প্রসারণ শব্দের উপর সম্পাদিত হয় না । যদি শব্দের কোনও অক্ষর উদ্ধৃত হয় তবে ডিলিমিটার শব্দের উপর উদ্ধৃতি অপসারণের ফলাফল এবং এখানে-নথির লাইনগুলি প্রসারিত হয় না। যদি শব্দটি উদ্ধৃত না করা হয় তবে এখানে-নথির সমস্ত লাইন প্যারামিটার সম্প্রসারণ, কমান্ড প্রতিস্থাপন এবং পাটিগণিতের বিস্তারের দ্বারা সাপেক্ষ। পরেরটির ক্ষেত্রে, চরিত্র ক্রম \<newline>উপেক্ষা করা হয়, এবং \অক্ষর উদ্ধৃত করা ব্যবহার করা আবশ্যক \, $এবং `

যদি পুনঃনির্দেশ অপারেটর হয় <<-তবে সমস্ত নেতৃস্থানীয় ট্যাব অক্ষরগুলি ইনপুট লাইন এবং ডিলিমিটারযুক্ত লাইন থেকে সরিয়ে নেওয়া হবে । এটি শেল স্ক্রিপ্টগুলির মধ্যে ডকুমেন্টগুলিকে প্রাকৃতিক ফ্যাশনে ইন্টেন্ট করতে দেয়।


12
ভেরিয়েবল / প্যারামিটার সম্প্রসারণ অক্ষম করতে আমার সবচেয়ে কঠিন সময় ছিল। আমাকে যা করতে হবে তা হ'ল "ডাবল-কোট" ব্যবহার করা এবং এটি এটি স্থির করে! তথ্যের জন্য ধন্যবাদ!
শিওনক্রস

11
সম্পর্কিত <<-দয়া করে মনে রাখবেন যে কেবল শীর্ষস্থানীয় ট্যাব অক্ষরগুলিই ছাঁটা হয়েছে - নরম ট্যাব অক্ষর নয়। আপনি যখন ট্যাব চরিত্রটি প্রয়োজন তখন এটি বিরল ক্ষেত্রে অন্যতম। যদি আপনার বাকী নথিটি নরম ট্যাব ব্যবহার করে তবে অদৃশ্য অক্ষরগুলি দেখানোর বিষয়টি নিশ্চিত করুন এবং (যেমন) কোনও ট্যাব অক্ষর অনুলিপি করুন এবং আটকান। আপনি যদি এটি সঠিকভাবে করেন তবে আপনার সিনট্যাক্স হাইলাইটিংয়ের সঠিকভাবে শেষের ডিলিমিটারটি ধরা উচিত।
trkoch

1
নীচের উত্তরগুলির চেয়ে এই উত্তরটি কীভাবে বেশি সহায়ক তা আমি দেখতে পাচ্ছি না। এটি কেবলমাত্র তথ্য
পুনরুদ্ধার করে

@ ব্রাডাহা, সম্ভবত এটি হয় না। এই প্রশ্ন কেন? upvotes কারণে? বেশ কয়েক বছর ধরে এটি ছিল একমাত্র। এটি তারিখের তুলনা করে দেখা যায়।
আলেক্সি মার্টিয়ানোভ

500

cat <<EOFসিনট্যাক্স খুব দরকারী যখন ব্যাশ মধ্যে বহু-লাইন পাঠ্য, যেমন সঙ্গে কাজ করছে। যখন শেল ভেরিয়েবল, ফাইল বা পাইপকে মাল্টি-লাইন স্ট্রিং বরাদ্দ করা হয়।

cat <<EOFবাশে সিনট্যাক্স ব্যবহারের উদাহরণ :

1. শেল ভেরিয়েবলে মাল্টি-লাইন স্ট্রিং বরাদ্দ করুন

$ sql=$(cat <<EOF
SELECT foo, bar FROM db
WHERE foo='baz'
EOF
)

$sqlপরিবর্তনশীল এখন নতুন লাইন অক্ষর খুব ঝুলিতে। আপনি যাচাই করতে পারেন echo -e "$sql"

2. বাশ-এ কোনও ফাইলে মাল্টি-লাইন স্ট্রিং পাস করুন

$ cat <<EOF > print.sh
#!/bin/bash
echo \$PWD
echo $PWD
EOF

print.shফাইলটি বর্তমানে রয়েছে:

#!/bin/bash
echo $PWD
echo /home/user

3. বাশের কোনও পাইপে মাল্টি-লাইন স্ট্রিংটি পাস করুন

$ cat <<EOF | grep 'b' | tee b.txt
foo
bar
baz
EOF

b.txtফাইল আছে barএবং bazলাইন। একই আউটপুট প্রিন্ট করা হয় stdout


1. 1 এবং 3 বিড়াল ছাড়াই করা যেতে পারে; 2. উদাহরণ 1 সাধারণ মাল্টি-লাইন স্ট্রিংয়ের সাহায্যে করা যেতে পারে
ড্যানিয়েল অল্ডার

268

আপনার ক্ষেত্রে, "ইওএফ" একটি "এখানে ট্যাগ" হিসাবে পরিচিত। মূলত শেলটিকে <<Hereবলে যে আপনি "ট্যাগ" অবধি একাধিক স্ট্রিং প্রবেশ করতে চলেছেন Here। আপনি চাইলে এই ট্যাগটির নাম রাখতে পারেন, এটি প্রায়শই EOFবা হয় STOP

এখানে ট্যাগ সম্পর্কে কিছু নিয়ম:

  1. ট্যাগটি কোনও স্ট্রিং, বড় হাতের বা ছোট হাতের অক্ষর হতে পারে, যদিও বেশিরভাগ লোক কনভেনশন অনুসারে বড় হাতের অক্ষর ব্যবহার করে।
  2. সেই লাইনে অন্য শব্দ থাকলে ট্যাগটিকে হিয়ার ট্যাগ হিসাবে বিবেচনা করা হবে না। এই ক্ষেত্রে, এটি কেবল স্ট্রিংয়ের অংশ হিসাবে বিবেচিত হবে। ট্যাগটি পৃথক লাইনে থাকা উচিত a
  3. ট্যাগ হিসাবে বিবেচিত হওয়ার জন্য এই লাইনে কোনও নেতৃস্থানীয় বা পিছনে স্থান নেই। অন্যথায় এটি স্ট্রিংয়ের অংশ হিসাবে বিবেচিত হবে।

উদাহরণ:

$ cat >> test <<HERE
> Hello world HERE <-- Not by itself on a separate line -> not considered end of string
> This is a test
>  HERE <-- Leading space, so not considered end of string
> and a new line
> HERE <-- Now we have the end of the string

30
এটিই সেরা আসল উত্তর ... আপনি উভয়টি সংজ্ঞায়িত করে এবং পরিষ্কারভাবে সম্পর্কিত তত্ত্বের পরিবর্তে ব্যবহারের প্রাথমিক উদ্দেশ্যটি বর্ণনা করেন ... যা গুরুত্বপূর্ণ তবে প্রয়োজনীয় নয় ... ধন্যবাদ - অতি সহায়ক
ওম্বাম 9090

5
@ এডেলানস আপনাকে অবশ্যই যোগ করতে হবে যে যখন <<-শীর্ষস্থানীয় ট্যাব ব্যবহার করা হয় তা ট্যাগকে স্বীকৃতি দেওয়া থেকে বিরত রাখে না
দ্য নাল-পয়েন্টার-

1
আপনার উত্তর আমাকে "আপনি একটি বহুলাইন স্ট্রিং প্রবেশ করতে চলেছেন" এ ক্লিক করেছেন
ক্যালকুলাস

79

পজিক্স 7

কেনেটিএম উদ্ধৃত হয়েছে man bash, তবে এর বেশিরভাগটি পসিএক্স 7: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_07_04 :

পুনঃনির্দেশ অপারেটরগুলি "<<" এবং "<< -" উভয়ই কমান্ডের ইনপুটটিতে "এখানে-নথি" হিসাবে পরিচিত শেল ইনপুট ফাইলের মধ্যে থাকা লাইনগুলির পুনঃনির্দেশের অনুমতি দেয়।

এখানে নথিতে একটি একক শব্দ হিসাবে বিবেচিত হবে যা পরের পরে শুরু হয় এবং অবধি অবধি অবধি অবধি অবধি অবধি অবধি চলতে থাকবে যতক্ষণ না এর মধ্যে কোন অক্ষর নেই। তারপরে পরবর্তী এখানে-নথিটি শুরু হয়, যদি একটি থাকে। ফর্ম্যাটটি নিম্নরূপ:

[n]<<word
    here-document
delimiter

যেখানে nচ্ছিক এন ফাইল বর্ণনাকারী নম্বর উপস্থাপন করে। যদি নম্বরটি বাদ দেওয়া হয় তবে এখানে-নথিটি স্ট্যান্ডার্ড ইনপুট (ফাইল বর্ণনাকারী 0) বোঝায়।

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

যদি শব্দের কোনও অক্ষরের উদ্ধৃতি না দেওয়া হয় তবে এখানে-নথির সমস্ত লাইন প্যারামিটার সম্প্রসারণ, কমান্ড প্রতিস্থাপন এবং পাটিগণিতের বিস্তারের জন্য প্রসারিত হবে। এই ক্ষেত্রে, ইনপুটটিতে অভ্যন্তরীণ ডাবল-কোট হিসাবে আচরণ করা হয় (ডাবল-কোটস দেখুন)। তবে ডাবল-কোট অক্ষর ('' ') এখানে একটি নথির মধ্যে বিশেষভাবে বিবেচনা করা হবে না, কেবলমাত্র "$ ())", "` `", বা "$ {}" এর মধ্যে ডাবল-কোট প্রদর্শিত হবে।

যদি পুনঃনির্দেশ প্রতীকটি "<< -" হয় তবে সমস্ত নেতৃস্থানীয় <tab> অক্ষরগুলি ইনপুট লাইন এবং পিছনের ডিলিমিটারযুক্ত লাইন থেকে সরিয়ে নেওয়া হবে। যদি একাধিক "<<" বা "<< -" অপারেটর একটি লাইনে নির্দিষ্ট করা থাকে, তবে প্রথম অপারেটরের সাথে সম্পর্কিত এই নথিটি প্রথমে অ্যাপ্লিকেশন দ্বারা সরবরাহ করা হবে এবং শেল দ্বারা প্রথমে পড়তে হবে।

যখন এখানে-নথিটি টার্মিনাল ডিভাইস থেকে পড়ে এবং শেলটি ইন্টারেক্টিভ হয়, তখন শেল ভেরিয়েবলগুলিতে বর্ণিত হিসাবে প্রসেস করা চলক PS2 এর বিষয়বস্তু লিখতে হবে, যতক্ষণ না ডিলিমিটারটি স্বীকৃত হয় ততক্ষণ ইনপুটটির প্রতিটি লাইন পড়ার আগে স্ট্যান্ডার্ড ত্রুটিতে error

উদাহরণ

কিছু উদাহরণ এখনও দেওয়া হয়নি।

উদ্ধৃতিগুলি প্যারামিটারের প্রসারণ রোধ করে

উক্তি ব্যতীত:

a=0
cat <<EOF
$a
EOF

আউটপুট:

0

উদ্ধৃতি সহ:

a=0
cat <<'EOF'
$a
EOF

বা (কুরুচিপূর্ণ তবে বৈধ):

a=0
cat <<E"O"F
$a
EOF

আউটপুট:

$a

হাইফেন নেতৃস্থানীয় ট্যাবগুলি সরিয়ে দেয়

হাইফেন ছাড়া:

cat <<EOF
<tab>a
EOF

কোথায় <tab>আক্ষরিক ট্যাবটি এবং এর সাথে সন্নিবেশ করা যায়Ctrl + V <tab>

আউটপুট:

<tab>a

হাইফেন সহ:

cat <<-EOF
<tab>a
<tab>EOF

আউটপুট:

a

এটি অবশ্যই উপস্থিত রয়েছে যাতে আপনি আপনার catচারপাশের কোডটি পছন্দ করতে পারেন যা পড়া এবং বজায় রাখা সহজ। উদাহরণ:

if true; then
    cat <<-EOF
    a
    EOF
fi

দুর্ভাগ্যক্রমে, এটি স্থানের অক্ষরের জন্য কাজ করে না: পসিক্স tabএখানে ইন্ডেন্টেশন পছন্দ করেছে । বাবা।


আপনার শেষ উদাহরণে আলোচনা করা <<-এবং <tab>a, এটি লক্ষ্য করা উচিত যে হেরডোক পাঠ্যটি প্রাপ্তি প্রক্রিয়াটিতে উপস্থাপনের সময় কলাম 0 এ শুরু করার অনুমতি দেওয়ার সময় স্ক্রিপ্টের মধ্যে কোডের স্বাভাবিক ইনডেন্টেশনকে অনুমতি দেওয়া ছিল এটি খুব বেশি দেখা যায় না এমন বৈশিষ্ট্য এবং কিছুটা আরও প্রসঙ্গ মাথা ঘামানো একটি ভাল চুক্তি রোধ করতে পারে ...
ডেভিড সি। র্যাঙ্কিন

1
আমার ইওএফ ট্যাগগুলির মধ্যে থাকা কিছু বিষয়বস্তু প্রসারিত করতে হবে এবং কিছু না করে কীভাবে আমি বহিরাগতদের হাতছাড়া করতে পারি?
জ্যানমিল কোট

2
... শুধু সামনে ব্যাকস্ল্যাশ ব্যবহার$
Jeanmichel কোত

@ জিনমিকেলকোট আমি এর চেয়ে ভাল বিকল্পটি দেখতে পাচ্ছি না :-) নিয়মিত স্ট্রিংয়ের সাহায্যে আপনি এই জাতীয় উক্তিগুলি মেশানোও বিবেচনা করতে পারেন "$a"'$b'"$c", তবে আফিকের কোনও এনালগ নেই।
সিওরো সান্তিলি :01 冠状 病 六四 事件 法轮功

25

বিড়ালের পরিবর্তে টি ব্যবহার করা হচ্ছে

মূল প্রশ্নের উত্তর হিসাবে ঠিক নয়, তবে আমি এটি যেভাবেই ভাগ করতে চেয়েছি: আমার একটি ডিরেক্টরিতে একটি কনফিগার ফাইল তৈরি করার দরকার ছিল যার মূল অধিকার প্রয়োজন।

নিম্নলিখিত ক্ষেত্রে এই ক্ষেত্রে কাজ করে না:

$ sudo cat <<EOF >/etc/somedir/foo.conf
# my config file
foo=bar
EOF

কারণ পুনঃনির্দেশটি সুডো প্রসঙ্গে বাইরে পরিচালনা করা হয়।

পরিবর্তে আমি এটি ব্যবহার করে শেষ করেছি:

$ sudo tee <<EOF /etc/somedir/foo.conf >/dev/null
# my config file
foo=bar
EOF

আপনার ক্ষেত্রে সুডো বাশ-সি 'বিড়াল << EOF> /etc/somedir/foo.conf # আমার কনফিগারেশন ফাইল foo = বার
ইওএফ

4

উপরের উত্তরগুলিতে একটু এক্সটেনশন। পিছনে> বিদ্যমান সামগ্রীতে ওভাররাইট করে ফাইলে ইনপুটটি নির্দেশ করে। তবে, একটি বিশেষ সুবিধাজনক ব্যবহার হ'ল ডাবল তীর >>যা যুক্ত হয়, আপনার নতুন সামগ্রীটি ফাইলের শেষে যুক্ত করে, যেমন:

cat <<EOF >> /etc/fstab
data_server:/var/sharedServer/authority/cert /var/sharedFolder/sometin/authority/cert nfs
data_server:/var/sharedServer/cert   /var/sharedFolder/sometin/vsdc/cert nfs
EOF

fstabদুর্ঘটনাক্রমে এর যে কোনও বিষয়বস্তু সংশোধন করার বিষয়ে আপনাকে চিন্তা না করে এটি আপনার প্রসারিত করে ।


1

এটি অগত্যা মূল প্রশ্নের উত্তর নয়, তবে আমার নিজের পরীক্ষা থেকে কিছু ফলাফল ভাগ করে নেওয়া। এই:

<<test > print.sh
#!/bin/bash
echo \$PWD
echo $PWD
test

হিসাবে একই ফাইল উত্পাদন করবে:

cat <<test > print.sh
#!/bin/bash
echo \$PWD
echo $PWD
test

সুতরাং, আমি ক্যাট কমান্ড ব্যবহার করার বিন্দুটি দেখতে পাচ্ছি না।


2
কোন শেল? আমি উবুন্টু 18.04 তে বাশ 4.4 এর পাশাপাশি ওএসএক্সে 3.2 ব্যাশ পরীক্ষা করেছি। দুজনেই খালি ফাইল তৈরি করেছেন যখন কেবল ব্যবহার <<testনা করে cat <<test
উইসবাকি

এটি আমার জন্য লিনাক্স মিন্টে ১৯ টি তারাতে কাজ করেছিল
জেডশ

0

এখানে লক্ষণীয় যে এখানে ডক্সও ব্যাশ লুপগুলিতে কাজ করে। এই উদাহরণটি দেখায় যে কীভাবে সারণির কলামের তালিকা পাবেন:

export postgres_db_name='my_db'
export table_name='my_table_name'

# start copy 
while read -r c; do test -z "$c" || echo $table_name.$c , ; done < <(cat << EOF | psql -t -q -d $postgres_db_name -v table_name="${table_name:-}"
SELECT column_name
FROM information_schema.columns
WHERE 1=1
AND table_schema = 'public'
AND table_name   =:'table_name'  ;
EOF
)
# stop copy , now paste straight into the bash shell ...

output: 
my_table_name.guid ,
my_table_name.id ,
my_table_name.level ,
my_table_name.seq ,

বা এমনকি নতুন লাইন ছাড়া

while read -r c; do test -z "$c" || echo $table_name.$c , | perl -ne 
's/\n//gm;print' ; done < <(cat << EOF | psql -t -q -d $postgres_db_name -v table_name="${table_name:-}"
 SELECT column_name
 FROM information_schema.columns
 WHERE 1=1
 AND table_schema = 'public'
 AND table_name   =:'table_name'  ;
 EOF
 )

 # output: daily_issues.guid ,daily_issues.id ,daily_issues.level ,daily_issues.seq ,daily_issues.prio ,daily_issues.weight ,daily_issues.status ,daily_issues.category ,daily_issues.name ,daily_issues.description ,daily_issues.type ,daily_issues.owner
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.