এই উত্তরগুলির বেশিরভাগটি আপনি যে নির্দিষ্ট ক্ষেত্রে জিজ্ঞাসা করছেন তাতে আঘাত করে। একটা সাধারণ পদ্ধতির এক বন্ধুর কাছে এবং আমি গড়ে তুলেছে যে অবাধ ক্ষেত্রে উদ্ধৃত আপনার যা দরকার জন্য করতে পারবেন করার উদ্ধৃতি ব্যাশ কমান্ড শেল সম্প্রসারণ, যেমন একাধিক স্তরের, SSH মাধ্যমে মাধ্যমে su -c
, bash -c
ইত্যাদি এক কোটি আদিম আপনার যা দরকার, এখানে নেই নেটিভ ব্যাশে:
quote_args() {
local sq="'"
local dq='"'
local space=""
local arg
for arg; do
echo -n "$space'${arg//$sq/$sq$dq$sq$dq$sq}'"
space=" "
done
}
এটি যা বলেছে ঠিক এটি করে: এটি প্রতিটি যুক্তি পৃথকভাবে শেল-কোট করে (অবশ্যই বাশ প্রসারণের পরে):
$ quote_args foo bar
'foo' 'bar'
$ quote_args arg1 'arg2 arg2a' arg3
'arg1' 'arg2 arg2a' 'arg3'
$ quote_args dq'"'
'dq"'
$ quote_args dq'"' sq"'"
'dq"' 'sq'"'"''
$ quote_args "*"
'*'
$ quote_args /b*
'/bin' '/boot'
এটি এক স্তরের সম্প্রসারণের জন্য সুস্পষ্ট কাজটি করে:
$ bash -c "$(quote_args echo a'"'b"'"c arg2)"
a"b'c arg2
(দ্রষ্টব্য যে চারপাশে দ্বৈত উদ্ধৃতিগুলি $(quote_args ...)
একক যুক্তিতে ফলাফল তৈরি করার জন্য প্রয়োজনীয় bash -c
)) এবং এটি প্রসারণের একাধিক স্তরগুলির মাধ্যমে সঠিকভাবে উদ্ধৃতি দেওয়ার জন্য আরও সাধারণভাবে ব্যবহার করা যেতে পারে:
$ bash -c "$(quote_args bash -c "$(quote_args echo a'"'b"'"c arg2)")"
a"b'c arg2
উপরের উদাহরণ:
- প্রতিটি আর্গুমেন্টকে শেল-
quote_args
স্বতন্ত্রভাবে কোট করে কোট করে এবং তারপরে ফলাফলটি আউটপুটটিকে একক যুক্তিতে অভ্যন্তরীণ ডাবল উদ্ধৃতিগুলির সাথে একত্রিত করে।
- শেল-কোট
bash
, -c
, এবং ধাপে 1 থেকে ইতিমধ্যে একসময়ের উদ্ধৃত ফলাফলের করুন, এবং তারপর বাইরের উদ্ধৃতি চিহ্ন সঙ্গে একটি একক যুক্তি মধ্যে ফলাফলের সম্মিলন।
- বাইরের থেকে আর্গুমেন্ট হিসাবে যে জগাখিচুড়ি পাঠায়
bash -c
।
সংক্ষেপে এই ধারণা। আপনি এটি দিয়ে বেশ কিছু জটিল জিনিস করতে পারেন, তবে আপনাকে মূল্যায়নের ক্রম এবং কোন সাবস্ট্রিংয়ের উদ্ধৃতি দেওয়া হয়েছে সে সম্পর্কে সতর্ক থাকতে হবে। উদাহরণস্বরূপ, নিম্নলিখিতগুলি ভুল জিনিসগুলি করে ("ভুল" এর কিছু সংজ্ঞার জন্য):
$ (cd /tmp; bash -c "$(quote_args cd /; pwd 1>&2)")
/tmp
$ (cd /tmp; bash -c "$(quote_args cd /; [ -e *sbin ] && echo success 1>&2 || echo failure 1>&2)")
failure
প্রথম উদাহরণে, ব্যাশটি তত্ক্ষণাত quote_args cd /; pwd 1>&2
দুটি পৃথক কমান্ডে প্রসারিত হয় quote_args cd /
এবং pwd 1>&2
তাই কমান্ডটি কার্যকর /tmp
হওয়ার পরে CWD এখনও থাকে pwd
। দ্বিতীয় উদাহরণটি গ্লোব্বিংয়ের জন্য একই ধরণের সমস্যার চিত্র তুলে ধরে। প্রকৃতপক্ষে, সমস্ত ব্যাশ বিস্তারে একই বুনিয়াদি সমস্যা দেখা দেয়। এখানে সমস্যাটি হ'ল কমান্ড প্রতিস্থাপনটি কোনও ফাংশন কল নয়: এটি আক্ষরিকভাবে একটি ব্যাশ স্ক্রিপ্টকে মূল্যায়ন করে এবং এর আউটপুটটিকে অন্য ব্যাশ স্ক্রিপ্টের অংশ হিসাবে ব্যবহার করে।
আপনি যদি শেল অপারেটরগুলি থেকে সহজেই পালানোর চেষ্টা করেন তবে আপনি ব্যর্থ হবেন কারণ এর ফলে প্রাপ্ত স্ট্রিংটি bash -c
কেবলমাত্র পৃথকভাবে উদ্ধৃত স্ট্রিংগুলির ক্রম যা অপারেটর হিসাবে ব্যাখ্যা করা হয় না, এটি যদি আপনি স্ট্রিং প্রতিধ্বনি করেন তবে এটি সহজেই দেখা যায় বাশকে দেওয়া হয়েছে:
$ (cd /tmp; echo "$(quote_args cd /\; pwd 1\>\&2)")
'cd' '/;' 'pwd' '1>&2'
$ (cd /tmp; echo "$(quote_args cd /\; \[ -e \*sbin \] \&\& echo success 1\>\&2 \|\| echo failure 1\>\&2)")
'cd' '/;' '[' '-e' '*sbin' ']' '&&' 'echo' 'success' '1>&2' '||' 'echo' 'failure' '1>&2'
এখানে সমস্যা হ'ল আপনি অতিরিক্ত উদ্ধৃতি দিচ্ছেন। অপারেটরদের এনকোলেটিংয়ের ইনপুট হিসাবে অকেজো হওয়া bash -c
মানে যা আপনার প্রয়োজন তা হ'ল $(quote_args ...)
কমান্ড প্রতিস্থাপনের বাইরে থাকা ।
ফলস্বরূপ, আপনাকে সবচেয়ে সাধারণ অর্থে যা করতে হবে তা হ'ল কমান্ডের প্রতিটি শব্দ পৃথকভাবে কমান্ড প্রতিস্থাপনের সময় প্রসারিত করার উদ্দেশ্যে নয়, এবং শেল অপারেটরদের জন্য কোনও অতিরিক্ত উদ্ধৃতি প্রয়োগ না করা:
$ (cd /tmp; echo "$(quote_args cd /); $(quote_args pwd) 1>&2")
'cd' '/'; 'pwd' 1>&2
$ (cd /tmp; bash -c "$(quote_args cd /); $(quote_args pwd) 1>&2")
/
$ (cd /tmp; echo "$(quote_args cd /); [ -e *$(quote_args sbin) ] && $(quote_args echo success) 1>&2 || $(quote_args echo failure) 1>&2")
'cd' '/'; [ -e *'sbin' ] && 'echo' 'success' 1>&2 || 'echo' 'failure' 1>&2
$ (cd /tmp; bash -c "$(quote_args cd /); [ -e *$(quote_args sbin) ] && $(quote_args echo success) 1>&2 || $(quote_args echo failure) 1>&2")
success
একবার এটি হয়ে গেলে, সম্পূর্ণ স্ট্রিংটি মূল্যায়নের স্বেচ্ছাসেবী স্তরের উদ্ধৃতি দেওয়ার জন্য ন্যায্য খেলা:
$ bash -c "$(quote_args cd /tmp); $(quote_args bash -c "$(quote_args cd /); $(quote_args pwd) 1>&2")"
/
$ bash -c "$(quote_args bash -c "$(quote_args cd /tmp); $(quote_args bash -c "$(quote_args cd /); $(quote_args pwd) 1>&2")")"
/
$ bash -c "$(quote_args bash -c "$(quote_args bash -c "$(quote_args cd /tmp); $(quote_args bash -c "$(quote_args cd /); $(quote_args pwd) 1>&2")")")"
/
$ bash -c "$(quote_args cd /tmp); $(quote_args bash -c "$(quote_args cd /); [ -e *$(quote_args sbin) ] && $(quote_args echo success) 1>&2 || $(quote_args echo failure) 1>&2")"
success
$ bash -c "$(quote_args bash -c "$(quote_args cd /tmp); $(quote_args bash -c "$(quote_args cd /); [ -e *sbin ] && $(quote_args echo success) 1>&2 || $(quote_args echo failure) 1>&2")")"
success
$ bash -c "$(quote_args bash -c "$(quote_args bash -c "$(quote_args cd /tmp); $(quote_args bash -c "$(quote_args cd /); [ -e *$(quote_args sbin) ] && $(quote_args echo success) 1>&2 || $(quote_args echo failure) 1>&2")")")"
success
প্রভৃতি
এই উদাহরণগুলি অতিমাত্রায় উত্তেজিত দেওয়া মনে হতে পারে যে শব্দ পছন্দ success
, sbin
এবং pwd
শেল-উদ্ধৃত করা প্রয়োজন হবে না, কিন্তু মূল বিষয়টা যখন একটি স্ক্রিপ্ট নির্বিচারে ইনপুট গ্রহণ লেখার মনে রাখা উচিত যে আপনি সবকিছু আপনি একেবারে নিশ্চিত না হন উদ্ধৃত করা চাই ফেলে না ' টি उद्धृत করা দরকার, কারণ আপনি কখনই বুঝতে পারবেন না যে কখন ব্যবহারকারী একটি এ ফেলবে Robert'; rm -rf /
।
কভারগুলির আওতায় কী চলছে তা আরও ভালভাবে বুঝতে, আপনি দুটি ছোট সহায়িকার কার্যকারিতা নিয়ে খেলতে পারেন:
debug_args() {
for (( I=1; $I <= $#; I++ )); do
echo -n "$I:<${!I}> " 1>&2
done
echo 1>&2
}
debug_args_and_run() {
debug_args "$@"
"$@"
}
এটি প্রতিটি আর্গুমেন্ট কার্যকর করার আগে একটি আদেশে গণনা করবে:
$ debug_args_and_run echo a'"'b"'"c arg2
1:<echo> 2:<a"b'c> 3:<arg2>
a"b'c arg2
$ bash -c "$(quote_args debug_args_and_run echo a'"'b"'"c arg2)"
1:<echo> 2:<a"b'c> 3:<arg2>
a"b'c arg2
$ bash -c "$(quote_args debug_args_and_run bash -c "$(quote_args debug_args_and_run echo a'"'b"'"c arg2)")"
1:<bash> 2:<-c> 3:<'debug_args_and_run' 'echo' 'a"b'"'"'c' 'arg2'>
1:<echo> 2:<a"b'c> 3:<arg2>
a"b'c arg2
$ bash -c "$(quote_args debug_args_and_run bash -c "$(quote_args debug_args_and_run bash -c "$(quote_args debug_args_and_run echo a'"'b"'"c arg2)")")"
1:<bash> 2:<-c> 3:<'debug_args_and_run' 'bash' '-c' ''"'"'debug_args_and_run'"'"' '"'"'echo'"'"' '"'"'a"b'"'"'"'"'"'"'"'"'c'"'"' '"'"'arg2'"'"''>
1:<bash> 2:<-c> 3:<'debug_args_and_run' 'echo' 'a"b'"'"'c' 'arg2'>
1:<echo> 2:<a"b'c> 3:<arg2>
a"b'c arg2
$ bash -c "$(quote_args debug_args_and_run bash -c "$(quote_args debug_args_and_run bash -c "$(quote_args debug_args_and_run bash -c "$(quote_args debug_args_and_run echo a'"'b"'"c arg2)")")")"
1:<bash> 2:<-c> 3:<'debug_args_and_run' 'bash' '-c' ''"'"'debug_args_and_run'"'"' '"'"'bash'"'"' '"'"'-c'"'"' '"'"''"'"'"'"'"'"'"'"'debug_args_and_run'"'"'"'"'"'"'"'"' '"'"'"'"'"'"'"'"'echo'"'"'"'"'"'"'"'"' '"'"'"'"'"'"'"'"'a"b'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'c'"'"'"'"'"'"'"'"' '"'"'"'"'"'"'"'"'arg2'"'"'"'"'"'"'"'"''"'"''>
1:<bash> 2:<-c> 3:<'debug_args_and_run' 'bash' '-c' ''"'"'debug_args_and_run'"'"' '"'"'echo'"'"' '"'"'a"b'"'"'"'"'"'"'"'"'c'"'"' '"'"'arg2'"'"''>
1:<bash> 2:<-c> 3:<'debug_args_and_run' 'echo' 'a"b'"'"'c' 'arg2'>
1:<echo> 2:<a"b'c> 3:<arg2>
a"b'c arg2