বাশের মধ্যে command (কমান্ড প্রতিস্থাপন) এর মধ্যে উদ্ধৃতি দেওয়া


126

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

আমার ভেরিয়েবলগুলি উদ্ধৃত করার সঠিক উপায় কী? এবং এগুলি বাসা বাঁধলে আমি কী করব?

DIRNAME=$(dirname "$FILE")

বা আমি বিকল্পের বাইরে উদ্ধৃতি দিতে পারি?

DIRNAME="$(dirname $FILE)"

অথবা উভয়?

DIRNAME="$(dirname "$FILE")"

বা আমি কি ব্যাক-টিক্স ব্যবহার করব?

DIRNAME=`dirname "$FILE"`

এটি করার সঠিক উপায় কী? এবং উদ্ধৃতিগুলি সঠিকভাবে সেট করা আছে কিনা আমি কীভাবে সহজেই পরীক্ষা করতে পারি?




1
এটি একটি ভাল প্রশ্ন, তবে এম্বেড থাকা ফাঁকা সমস্ত বিষয় দেওয়া সত্ত্বেও, আপনি কেন তাদের উদ্দেশ্য করে ব্যবহার করে জীবনকে কঠোর করবেন?
জো

3
@ জো, এম্বেড থাকা ফাঁকা জায়গায় আপনি ফাইলের নাম বলতে চান? ব্যক্তিগতভাবে আমি এগুলি প্রায়শই ব্যবহার করি না, তবে আমি অন্যান্য লোক ডিরেক্টরিতে এবং ফাইলগুলির সাথে কাজ করছি যার মধ্যে স্পেস রয়েছে কিনা তা সম্পর্কে আমি নিশ্চিত নই। তদুপরি, আমি মনে করি এটি ঠিক একবারে পাওয়া ভাল তাই ভবিষ্যতে আমাকে চিন্তা করতে হবে না।
কাজিনকোচেন

4
হ্যাঁ. আমরা এই "অন্যান্য লোক" সাথে কী করব? <G>
জো

উত্তর:


188

সবচেয়ে খারাপ থেকে সেরা পর্যন্ত:

  • DIRNAME="$(dirname $FILE)" $FILEশ্বেতক্ষেত্র বা গ্লোববিং অক্ষর থাকলে আপনি যা চান তা করবে না\[?*
  • DIRNAME=`dirname "$FILE"`প্রযুক্তিগতভাবে সঠিক, তবে ব্যাকটিকগুলি বাসা বাঁধাকালীন অতিরিক্ত জটিলতার কারণে কমান্ড প্রসারণের জন্য সুপারিশ করা হয় না
  • DIRNAME=$(dirname "$FILE")সঠিক, তবে কেবলমাত্র এটি একটি অ্যাসাইনমেন্ট । আপনি যদি অন্য কোনও প্রসঙ্গে কমান্ড প্রতিস্থাপন ব্যবহার করেন, যেমন export DIRNAME=$(dirname "$FILE")বা du $(dirname "$FILE"), উদ্ধৃতিগুলির অভাব যদি সমস্যার ফাঁকে ফাঁকে ফাঁকে ফাঁকা জায়গা বা গ্লোববিং অক্ষর ধারণ করে তবে সমস্যা দেখা দিতে পারে।
  • DIRNAME="$(dirname "$FILE")"প্রস্তাবিত উপায়। আপনি DIRNAME=অন্য কোনও কিছু পরিবর্তন না করে একটি কমান্ড এবং একটি স্থান দিয়ে প্রতিস্থাপন করতে পারেন এবং dirnameসঠিক স্ট্রিংটি পাবেন।

আরও উন্নতি করতে:

  • DIRNAME="$(dirname -- "$FILE")"$FILEড্যাশ দিয়ে শুরু হলে কাজ করে ।
  • DIRNAME="$(dirname -- "$FILE"; printf x)" && DIRNAME="${DIRNAME%?x}"এমনকি যদি $FILEনিউলাইন দিয়ে শেষ হয় তবে কাজ করে , যেহেতু $()আউটপুট শেষে dirnameনিউলাইনগুলি ছড়িয়ে যায় এবং ফলাফলের পরে একটি নতুন লাইন আউটপুট করে। শীশ dirname, তুমি কেন আলাদা হবে?

আপনি নিজের পছন্দ অনুসারে বাসা বাঁধতে পারেন। আপনার সাথে $()সর্বদা একটি নতুন উদ্ধৃতি প্রসঙ্গে তৈরি করা হয়, যাতে আপনি এই জাতীয় জিনিসগুলি করতে পারেন:

foo "$(bar "$(baz "$(ban "bla")")")"

আপনি ব্যাকটিক্স দিয়ে এটি চেষ্টা করতে চান না


3
আমার প্রশ্নের পরিষ্কার উত্তর। আমি যখন এই ভেরিয়েবলগুলিকে বাসা বেঁধে রাখি, আমি কি এখনকার মতো করে উদ্ধৃত করে রাখতে পারি?
কাজিনকোচেন

3
উদ্ধৃতিগুলির মধ্যে একটি কমান্ড সাবস্টিস্টেশনের মধ্যে কোটগুলির আচরণের বিশদ সম্পর্কিত কোন রেফারেন্স / সংস্থান আছে?
AmadeusDrZaius

12
@ আমেডাসড্রজাইউস "আপনার সাথে $()সর্বদা একটি নতুন উদ্ধৃতি প্রসঙ্গে তৈরি করুন", সুতরাং এটি ঠিক বাইরের উদ্ধৃতিগুলির মতো। যতদূর আমি জানি এটির আর কিছুই নেই।
l0b0

4
@ l0b0 ধন্যবাদ, হ্যাঁ, আমি আপনার ব্যাখ্যাটি খুব পরিষ্কার পেয়েছি। আমি কেবল ভাবছিলাম যে এটি কোথাও ম্যানুয়ালটিতে রয়েছে কিনা। আমি এটি (আনুষ্ঠানিকভাবে যাই হোক না কেন) wooledge এ পেয়েছি । আমার ধারণা আপনি যদি প্রতিস্থাপনের আদেশটি সাবধানতার সাথে পড়েন , ফলস্বরূপ আপনি এই সত্যটি অর্জন করতে পারেন।
AmadeusDrZaius

1
সুতরাং নেস্টেড উক্তি গ্রহণযোগ্য, তবে তারা আমাদের ফেলে দেয় কারণ বেশিরভাগ সিনট্যাক্স রঙিন স্কিমগুলি বিশেষ পরিস্থিতি সনাক্ত করে না। ঝরঝরে।
লুক ডেভিস

19

আপনি সর্বদা এর সাথে ভেরিয়েবল উদ্ধৃতির প্রভাবগুলি প্রদর্শন করতে পারেন printf

শব্দ বিভাজন এখানে সম্পন্ন var1:

$ var1="hello     world"
$ printf '[%s]\n' $var1
[hello]
[world]

var1 উদ্ধৃত, তাই কোনও শব্দ বিভাজন:

$ printf '[%s]\n' "$var1"
[hello     world]

এর var1ভিতরে শব্দের বিভাজন $(), সমান echo "hello" "world":

$ var2=$(echo $var1)
$ printf '[%s]\n' "$var2"
[hello world]

কোনও শব্দের বিভক্তি নেই var1, উদ্ধৃতি না দিয়ে কোনও সমস্যা নেই $():

$ var2=$(echo "$var1")
$ printf '[%s]\n' "$var2"
[hello     world]

var1আবার শব্দ বিভাজন :

$ var2="$(echo $var1)"
$ printf '[%s]\n' "$var2"
[hello world]

উভয়ই উদ্ধৃত করা, নিশ্চিত হওয়া সবচেয়ে সহজ উপায়।

$ var2="$(echo "$var1")"
$ printf '[%s]\n' "$var2"
[hello     world]

সমস্যা সমাধান

কোনও ভেরিয়েবলের উদ্ধৃতি না দেওয়ার ফলে এর বিষয়বস্তুগুলি বিশ্বব্যাপী প্রসারিত করতে পারে:

$ mkdir test; cd test; touch file1 file2
$ var="*"
$ printf '[%s]\n' $var
[file1]
[file2]
$ printf '[%s]\n' "$var"
[*]

নোট করুন কেবল ভেরিয়েবলটি প্রসারিত হওয়ার পরে এটি ঘটে। অ্যাসাইনমেন্টের সময় গ্লোব উদ্ধৃতি দেওয়ার প্রয়োজন হয় না:

$ var=*
$ printf '[%s]\n' $var
[file1]
[file2]
$ printf '[%s]\n' "$var"
[*]

set -fএই আচরণটি অক্ষম করতে ব্যবহার করুন :

$ set -f
$ var=*
$ printf '[%s]\n' $var
[*]

এবং set +fএটি পুনরায় সক্ষম করতে:

$ set +f
$ printf '[%s]\n' $var
[file1]
[file2]

8
লোকেদের ভুলে যাওয়ার ঝোঁক রয়েছে যে শব্দ var1='hello * world'বিভাজনই একমাত্র সমস্যা নয়, আপনি বিশ্বব্যাপী সমস্যাটিও চিত্রিত করতে আপনার উদাহরণ পরিবর্তন করতে পারেন ।
স্টাফেন চেজেলাস

10

গৃহীত উত্তরের সাথে যুক্ত করুন:

যদিও আমি এখানে @ l0b0 এর উত্তরের সাথে একমত , আমার সন্দেহ হয় যে "সবচেয়ে খারাপ থেকে সেরা" তালিকায় খালি ব্যাকটিকের স্থান নির্ধারণ অন্ততপক্ষে যে কোনও $(...)জায়গায় পাওয়া যায় এমন অনুমানের ফলস্বরূপ । আমি বুঝতে পারি যে প্রশ্নটি ব্যাশকে নির্দিষ্ট করে, তবে প্রচুর সময় আসে যখন ব্যাশ মানে বোঝায় /bin/sh, যা সর্বদা বাস্তবে পুরো বোর্ন অ্যাগেইন শেল নাও হতে পারে।

বিশেষত, সরল বোর্ন শেলটি কী করবে তা জানবে না $(...), সুতরাং যে স্ক্রিপ্টগুলি এর সাথে সামঞ্জস্যপূর্ণ বলে দাবি করে (যেমন, #!/bin/shশেবাং লাইনের মাধ্যমে ) সম্ভবত "রিয়েল" দ্বারা চালিত হলে সম্ভবত এটি খারাপ আচরণ করবে /bin/sh- এটি হ'ল বিশেষ আগ্রহ যখন, বলুন, init স্ক্রিপ্টগুলি উত্পাদন করা, বা প্যাকেজিং প্রাক- এবং পোস্ট-স্ক্রিপ্টগুলি, এবং বেস সিস্টেমটি ইনস্টল করার সময় একটি অবাক করা জায়গায় পৌঁছতে পারে।

আপনি যদি এই ভেরিয়েবলটি নিয়ে কিছু করার পরিকল্পনা করছেন এমন কিছু মনে হয় তবে সম্ভবত স্ক্রিপ্টটি থাকার চেয়ে বাসা বাঁধাই কোনও উদ্বেগের বিষয় নয়, সম্ভবত চালানো run যখন এটি একটি সহজ পর্যাপ্ত কেস এবং বহনযোগ্যতা একটি উদ্বেগ, এমনকি আমি যদি স্ক্রিপ্টটি সাধারণত/bin/sh ব্যাশ যেখানে রয়েছে এমন সিস্টেমে চালিত হওয়ার আশা করি , আমি প্রায়শই বাসা বাঁধার পরিবর্তে একাধিক অ্যাসাইনমেন্ট সহ এই কারণে ব্যাকটিক্স ব্যবহার করার প্রবণতা রাখি।

সব বলার পরে, শেলগুলির সর্বব্যাপীতা $(...)(বাশ, ড্যাশ, ইত্যাদি ইত্যাদি) বাস্তবায়ন করে , বেশিরভাগ ক্ষেত্রে আমাদের পছন্দসই, সহজ-নীড় থেকে নীড়, এবং আরও সম্প্রতি পছন্দ করা পসিক্স সিনট্যাক্সের সাথে লেগে থাকার জন্য একটি ভাল জায়গায় ফেলে দেয় for সমস্ত কারণ @ l0b0 উল্লেখ করেছে।

পাশে: স্ট্যাকওভারফ্লোতেও এটি মাঝে মধ্যে প্রদর্শিত হয়েছিল -


//, দুর্দান্ত উত্তর। আমি অতীতেও / বিন / শ এর সাথে পিছনের দিকে সামঞ্জস্যতার সমস্যাগুলিতে চলে এসেছি। পশ্চাদগামী সামঞ্জস্যপূর্ণ পদ্ধতি ব্যবহার করে কীভাবে তার সমস্যা মোকাবেলা করতে হবে তার সম্পর্কে আপনার কোনও পরামর্শ আছে?
নাথান বাসানিজ

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