මෙම පිළිතුරු බොහොමයක් ඔබ අසන විශේෂිත නඩුවට පහර දෙයි. අත්තනෝමතික ඔබ උදා, 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 ...)
result ලය තනි තර්කයක් බවට පත් කිරීම සඳහා අවට ඇති ද්විත්ව උපුටා දැක්වීම් අවශ්ය බව සලකන්න bash -c
.) තවද එය පුළුල් කිරීමේ විවිධ ස්ථර හරහා නිසි ලෙස උපුටා දැක්වීමට වඩාත් සාමාන්යයෙන් භාවිතා කළ හැකිය:
$ bash -c "$(quote_args bash -c "$(quote_args echo a'"'b"'"c arg2)")"
a"b'c arg2
ඉහත උදාහරණය:
- shell-quotes එක් එක් තර්කය අභ්යන්තරයට
quote_args
තනි තනිව උපුටා දක්වන අතර එහි ප්රති output ලය වන ප්රතිදානය අභ්යන්තර ද්විත්ව උපුටා දැක්වීම් සමඟ තනි තර්කයකට ඒකාබද්ධ කරයි.
- shell-quotes
bash
, -c
සහ 1 වන පියවරෙන් දැනටමත් උපුටා දක්වා ඇති ප්රති result ලය, ඉන්පසු ප්රති double ලය පිටත ද්විත්ව උපුටා දැක්වීම් සමඟ තනි තර්කයකට ඒකාබද්ධ කරයි.
- එම අවුල තර්කය ලෙස පිටතින් යවයි
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
පළමු උදාහරණයේදී, bash වහාම පුළුල් quote_args cd /; pwd 1>&2
වෙනම විධාන දෙකකට, quote_args cd /
හා pwd 1>&2
, එම නිසා CWD තවමත් /tmp
වූ විට pwd
අණ ක්රියාත්මක කර ඇත. දෙවන උදාහරණයෙන් ග්ලෝබ් කිරීම සඳහා සමාන ගැටළුවක් නිරූපණය වේ. ඇත්ත වශයෙන්ම, සියලු මූලික පුළුල් කිරීම් වලදී එකම මූලික ගැටළුව ඇතිවේ. මෙහි ඇති ගැටළුව නම් විධාන ආදේශනය ක්රියාකාරී ඇමතුමක් නොවීමයි: එය වචනාර්ථයෙන් එක් බැෂ් ස්ක්රිප්ට් එකක් තක්සේරු කර එහි ප්රතිදානය වෙනත් බෑෂ් ස්ක්රිප්ටයක කොටසක් ලෙස භාවිතා කරයි.
ඔබ හුදෙක් ෂෙල් ක්රියාකරුවන්ගෙන් බේරීමට උත්සාහ කරන්නේ නම්, ඔබ අසමත් වනුයේ එහි bash -c
ප්රති string ලයක් ලෙස ලබා දෙන නූල තනි තනිව උපුටා දක්වන ලද නූල්වල අනුක්රමයක් වන අතර එය ක්රියාකරුවන් ලෙස අර්ථ නිරූපණය නොකෙරේ. කඩාවැටීමට සම්මත කර ඇත:
$ (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 ...)
විධාන ආදේශනයට පිටතින් සිටිය යුතු බවයි .
එහි ප්රති sequently ලයක් වශයෙන්, ඔබ කළ යුත්තේ සාමාන්ය අර්ථයෙන් විධාන ආදේශන අවස්ථාවේ දී පුළුල් කිරීමට අදහස් නොකරන විධානයන්හි එක් එක් වචනය වෙන වෙනම ෂෙල්-කෝට් කිරීම සහ ෂෙල් ක්රියාකරුවන්ට අමතර උපුටා දැක්වීමක් නොකිරීම ය:
$ (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
ආදිය.
මෙම උදාහරණ වැනි වචන බව ලබා දී overwrought පෙනුණත් 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