অন্য স্ক্রিপ্টের বিষয়বস্তু হিসাবে ব্যবহারের জন্য একটি ভেরিয়েবল এড়িয়ে চলুন


20

এই প্রশ্নটি কীভাবে সঠিকভাবে পালানো স্ট্রিং আক্ষরিক লিখতে হবে তা নয় । কোনও স্ক্রিপ্টের মধ্যে বা অন্যান্য প্রোগ্রামের মাধ্যমে সরাসরি ব্যবহারের জন্য ভেরিয়েবলগুলি কীভাবে পালাতে হয় সে সম্পর্কিত কোনও সম্পর্কিত প্রশ্ন আমি খুঁজে পেলাম না।

আমার লক্ষ্য হ'ল অন্যান্য স্ক্রিপ্টগুলি তৈরি করতে কোনও স্ক্রিপ্ট সক্ষম করা। এর কারণ, উত্পাদিত স্ক্রিপ্টগুলির কাজগুলি অন্য মেশিনে 0 থেকে n বার যে কোনও জায়গায় চলবে এবং যে তথ্য থেকে তারা উত্পন্ন হয় সেগুলি আবার চালানোর আগেই পরিবর্তন হতে পারে (আবার), সুতরাং সরাসরি নেটওয়ার্কে অপারেশনগুলি সম্পাদন করে কাজ করে না.

একটি পরিচিত পরিবর্তনশীল যে এই ধরনের একক উদ্ধৃতি হিসাবে বিশেষ অক্ষর থাকতে পারে দেওয়া, আমি যে লিখতে একটি সম্পূর্ণরূপে পলান স্ট্রিং আক্ষরিক, যেমন একটি পরিবর্তনশীল হিসাবে প্রয়োজন fooধারণকারী bar'bazহিসাবে উত্পন্ন লিপিতে প্রদর্শিত হওয়া উচিত:

qux='bar'\''baz'

যা "qux=$foo_esc"স্ক্রিপ্টের অন্যান্য লাইনে যুক্ত করে লেখা হবে। আমি এটি পার্ল ব্যবহার করে এটি করেছি:

foo_esc="'`perl -pe 's/('\'')/\\1\\\\\\1\\1/g' <<<"$foo"`'"

তবে এটি ওভারকিলের মতো বলে মনে হচ্ছে।

একা বাশ দিয়ে এটি করার ক্ষেত্রে আমার কোনও সাফল্য নেই। আমি এর বিভিন্ন প্রকরণ চেষ্টা করেছি:

foo_esc="'${file//\'/\'\\\'\'}'"
foo_esc="'${file//\'/'\\''}'"

তবে হয় অতিরিক্ত স্ল্যাশগুলি আউটপুটে উপস্থিত হয় (যখন আমি করি echo "$foo") অথবা তারা একটি সিনট্যাক্স ত্রুটির সৃষ্টি করে (শেল থেকে করা হলে আরও ইনপুট প্রত্যাশা করে)।


aliasএবং / অথবা setমোটামুটি সর্বজনীন
মাইক্রজারভ

@ মিমকিজার দুঃখিত, আপনি কী বলতে চাইছেন তা আমি নিশ্চিত নই।
ওয়ালফ

alias "varname=$varname" varnameবাvar=value set
মাইকসার্ভ

2
@ মাইকজার্ভ আপনার পরামর্শটি কী করণীয় তা বোঝার পক্ষে আমার পক্ষে এটি পর্যাপ্ত প্রসঙ্গ নয় বা আমি কীভাবে এটিকে কোনও পরিবর্তনশীল থেকে বাঁচার জেনেরিক পদ্ধতি হিসাবে ব্যবহার করব। এটি একটি সমাধান সমস্যা, সাথী।
ওয়াল্ফ

উত্তর:


27

ঠিক এই ক্ষেত্রে বাশের একটি প্যারামিটার সম্প্রসারণ বিকল্প রয়েছে :

${parameter@Q}সম্প্রসারণ একটি স্ট্রিং যা ইনপুট হিসাবে পুনরায় ব্যবহার করা যেতে পারে এমন ফর্ম্যাটে উদ্ধৃত প্যারামিটারের মান ।

সুতরাং এই ক্ষেত্রে:

foo_esc="${foo@Q}"

এটি ৪.৪ বাশ এবং তার চেয়ে বেশি ক্ষেত্রে সমর্থিত। অন্যান্য ধরণের সম্প্রসারণের জন্য এবং বিশেষভাবে সম্পূর্ণ কার্যনির্বাহী বিবৃতি ( @A) উত্পন্ন করার জন্য বিভিন্ন বিকল্প রয়েছে ।


7
ঝরঝরে, তবে কেবল 4.2 রয়েছে যা দেয় bad substitution
ওয়াল্ফ

3
জেড শেল সমতুল্য "${foo:q}"
JdeBP

সত্যিই আমার জীবন বাঁচাও! "${foo@Q}"কাজ করে!
হাও

@ জেডিবিপি যে জেড শেল সমতুল্য কাজ করে না। Zsh জন্য অন্য কোন ধারণা?
স্টিভেন শ

1
আমি উত্তরটি পেয়েছি: "$ {(@ কিউকিউ) ফু}"
স্টিভেন শ

11

বাশ একটি ফর্ম্যাট স্পেসিফায়ার printfসহ একটি বিল্টিন সরবরাহ করে %q, যা বাশের পুরানো (<4.0) সংস্করণেও আপনার জন্য শেল পলায়নের কাজ করে:

printf '[%q]\n' "Ne'er do well"
# Prints [Ne\'er\ do\ well]

printf '[%q]\n' 'Sneaky injection $( whoami ) `ls /root`'
# Prints [Sneaky\ injection\ \$\(\ whoami\ \)\ \`ls\ /root\`]

এই কৌশলটি কোনও ফাংশন থেকে ডেটার অ্যারে ফিরিয়ে আনতেও ব্যবহার করা যেতে পারে:

function getData()
{
  printf '%q ' "He'll say hi" 'or `whoami`' 'and then $( byebye )'
}

declare -a DATA="( $( getData ) )"
printf 'DATA: [%q]\n' "${DATA[@]}"
# Prints:
# DATA: [He\'ll\ say\ hi]
# DATA: [or\ \`whoami\`]
# DATA: [and\ then\ \$\(\ byebye\ \)]

মনে রাখবেন যে ব্যাশ printfবিল্টিনটি printfইউটিলিটির চেয়ে আলাদা যা বেশিরভাগ ইউনিক্স-এর মতো অপারেটিং সিস্টেমের সাথে বান্ডিল হয়। যদি, কোনও কারণে, printfকমান্ডটি বিল্টিনের পরিবর্তে ইউটিলিটিটি আহ্বান করে, আপনি builtin printfতার পরিবর্তে সর্বদা কার্যকর করতে পারেন ।


আমি যে কিভাবে নিশ্চিত না করতে সাহায্য করে যদি কি আমি প্রয়োজন চাই আছি মুদ্রিত হবে 'Ne'\''er do well'ইত্যাদি, অর্থাৎ কোট আউটপুট অন্তর্ভুক্ত করা হয়েছে।
ওয়াল্ফ

1
@ ওয়াল্ফ আমি মনে করি আপনি বুঝতে পারছেন না যে দুটি রূপ সমান এবং উভয়ই একে অপরের মতো পুরোপুরি নিরাপদ। যেমন [[ 'Ne'\''er do well' == Ne\'er\ do\ well ]] && echo 'equivalent!'echo হবেequivalent!
Dejay ক্লেটন

আমি এটি মিস করেছি: পি তবে আমি উদ্ধৃত ফর্মটি পছন্দ করি কারণ একটি সিনট্যাক্স-হাইলাইটিং ভিউয়ার / সম্পাদকটিতে পড়া সহজ।
ওয়ালফ

@ ওয়াল্ফ দেখে মনে হচ্ছে আপনার পদ্ধতিটি বেশ বিপজ্জনক, কারণ আপনার উদাহরণে পার্ল, ভ্যালুতে 'hello'ফলাফলের মতো একটি মান পাস করে ''\''hello''যা একটি অপ্রয়োজনীয় শীর্ষস্থানীয় খালি স্ট্রিং (প্রথম দুটি একক উদ্ধৃতি) এবং একটি অনুপযুক্ত ট্রেলিং একক উক্তি রয়েছে।
দেজে ক্লেটন

1
@Walf, শোধন জন্য, $'escape-these-chars'হয় ANSI-সি উদ্ধৃত ব্যাশ বৈশিষ্ট্য ঘটায় যে চিহ্নিত স্ট্রিংয়ের মধ্যে সমস্ত অক্ষর পলান করা হবে। সুতরাং সহজেই একটি স্ট্রিং লিটারেল তৈরি করতে যা ফাইলনামের মধ্যে একটি নতুন লাইন থাকে (উদাহরণস্বরূপ $'first-line\nsecond-line'), \nএই নির্মাণের মধ্যে ব্যবহার করুন
দেজয় ক্লেটন

8

আমার ধারণা আমি আরটিএফএম করিনি। এটি এর মতো করা যেতে পারে:

q_mid=\'\\\'\'
foo_esc="'${foo//\'/$q_mid}'"

তারপর echo "$foo_esc"প্রত্যাশিত দেয়'bar'\''baz'


আমি আসলে এটি কীভাবে ব্যবহার করছি এটি একটি ফাংশন সহ:

function esc_var {
    local mid_q=\'\\\'\'
    printf '%s' "'${1//\'/$mid_q}'"
}

...

foo_esc="`esc_var "$foo"`"

printfদেজার সমাধান থেকে বিল্ট-ইনটি ব্যবহার করতে এটি পরিবর্তন করে :

function esc_vars {
    printf '%q' "$@"
}

3
আমি যদি আমার সংস্করণটিকে সমর্থন করে তবে আমি @ মাইকেল-হোমারের সমাধানটি ব্যবহার করব।
ওয়াল্ফ

4

বিভিন্ন মানের মূল্য উদ্ধৃত করার জন্য কয়েকটি সমাধান রয়েছে:

  1. ওরফে
    বেশিরভাগ শেলগুলিতে (যেখানে উরফ পাওয়া যায়) (সিএসএস, টিসিএস এবং সম্ভবত অন্যরা সিএসএস ছাড়া):

    $ alias qux=bar\'baz
    $ alias qux
    qux='bar'\''baz'

    হ্যাঁ, এটি shড্যাশ বা ছাইয়ের মতো অনেকগুলি পছন্দ মতো শেলগুলিতে কাজ করে ।


  2. বেশিরভাগ শাঁসে এছাড়াও সেট করুন (আবার, সিএসএস নয়):

    $ qux=bar\'baz
    $ set | grep '^qux='
    qux='bar'\''baz'
  3. টাইপসেট
    কিছু শেল (ksh, বাশ এবং কমপক্ষে zsh):

    $ qux=bar\'baz
    $ typeset -p qux
    typeset qux='bar'\''baz'             # this is zsh, quoting style may
                                         # be different for other shells.
  4. রফতানি করুন
    প্রথম:

    export qux=bar\'baz

    তারপরে ব্যবহার করুন:
    export -p | grep 'qux=' export -p | grep 'qux='
    export -p qux

  5. এক থেকে চার কিউ এর কোট
    echo "${qux@Q}"
    echo "${(qq)qux}" # ব্যবহার করা যেতে পারে।


উপনাম পদ্ধতির চালাক এবং এটি পসিক্স দ্বারা নির্দিষ্ট করা আছে বলে মনে হচ্ছে। সর্বাধিক বহনযোগ্যতার জন্য আমি মনে করি এটিই যাওয়ার উপায়। আমি বিশ্বাস করি যে এমবেড করা নিউলাইনগুলি যুক্ত ভেরিয়েবলগুলির grepসাথে জড়িত exportবা setভেঙে যেতে পারে।
jw013
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.