පයිතන් ස්ක්රිප්ට් එකකින් බාහිර විධානයක් (මම එය යුනික්ස් ෂෙල් හෝ වින්ඩෝස් විධාන විමසුමේ ටයිප් කළාක් මෙන්) අමතන්නේ කෙසේද?
පයිතන් ස්ක්රිප්ට් එකකින් බාහිර විධානයක් (මම එය යුනික්ස් ෂෙල් හෝ වින්ඩෝස් විධාන විමසුමේ ටයිප් කළාක් මෙන්) අමතන්නේ කෙසේද?
Answers:
සම්මත පුස්තකාලයේ උප සැකසුම් මොඩියුලය දෙස බලන්න :
import subprocess
subprocess.run(["ls", "-l"])
subprocess
එදිරිව ඇති වාසිය system
නම් එය වඩාත් නම්යශීලී වීමයි (ඔබට එය ලබා ගත හැකිය stdout
,stderr
"සැබෑ" තත්ත්වය කේතය, වඩා හොඳ දෝෂයක් හැසිරවීම, etc ...).
මෙම නිල ප්රලේඛනය නිර්දේශ subprocess
විකල්ප කට මොඩියුලය os.system()
:
මෙම
subprocess
මොඩියුලය නව ක්රියාවලි වීමේදී හා ඔවුන්ගේ ප්රතිඵල දැන ගැනීම සඳහා වඩා බලවත් පහසුකම් සළසන බවත්; මෙම ශ්රිතය භාවිතා කිරීමට වඩා එම මොඩියුලය භාවිතා කිරීම වඩාත් සුදුසුය [os.system()
].
මෙම වන subprocess මොඩියුලය සමඟ වෙනුවට පැරණි කාර්යයන් තුළ කොටස subprocess
ප්රලේඛනය සමහර ප්රයෝජනවත් වට්ටෝරු තිබිය හැක.
3.5 ට පෙර පයිතන් අනුවාද සඳහා, භාවිතා කරන්න call
:
import subprocess
subprocess.call(["ls", "-l"])
shell=True
ඒ සඳහා වැඩ කිරීමට ඔබට සිදුවේ.
shell=True
, මේ සඳහා පයිතන් os.path.expandvars සමඟ පැමිණේ . ඔබේ නඩුවේදී ඔබට ලිවිය හැකිය : os.path.expandvars("$PATH")
. EthSethMMorton කරුණාකර ඔබේ අදහස නැවත සලකා බලන්න -> shell භාවිතා නොකරන්නේ ඇයි = ඇත්ත
for
ලූපයක් තුළ ධාවනය කිරීමට අවශ්ය නම් එය මගේ පයිතන් ස්ක්රිප්ට් අවහිර නොකර එය කරන්නේ කෙසේද? මට ඒවායින් බොහොමයක් ධාවනය කිරීමට අවශ්ය විධානයේ ප්රතිදානය ගැන මට ප්රශ්නයක් නැත.
subprocess
විට shell=False
එවකට භාවිතා කරන්න, shlex.split
මෙය කිරීමට පහසු ක්රමයක් සඳහා docs.python.org/2/library/shlex.html#shlex.split
බාහිර වැඩසටහන් ඇමතීමේ ක්රම සහ එක් එක් ඒවායේ වාසි සහ අවාසි පිළිබඳ සාරාංශයක් මෙන්න:
os.system("some_command with args")
විධානය සහ තර්ක ඔබේ පද්ධතියේ කවචයට යවයි. මෙය කදිමයි, මන්ද ඔබට සැබවින්ම මේ ආකාරයෙන් එකවර විධාන කිහිපයක් ක්රියාත්මක කළ හැකි අතර පයිප්ප සහ ආදාන / ප්රතිදාන යළි-යොමුවීම් සැකසිය හැකිය. උදාහරණයක් වශයෙන්:
os.system("some_command < input_file | another_command > output_file")
කෙසේ වෙතත්, මෙය පහසු වන අතර, අවකාශය වැනි ෂෙල් අක්ෂර වලින් ගැලවී යාම ඔබ විසින් අතින් සිදු කළ යුතුය. අනෙක් අතට, මෙය හුදෙක් විධාන ක්රියාත්මක කිරීමට ඉඩ සලසයි, ඒවා හුදෙක් ෂෙල් විධාන වන අතර ඇත්ත වශයෙන්ම බාහිර වැඩසටහන් නොවේ. ප්රලේඛනය බලන්න .
stream = os.popen("some_command with args")
os.system
එම ක්රියාවලිය සඳහා සම්මත ආදානය / ප්රතිදානය වෙත පිවිසීමට ඔබට භාවිතා කළ හැකි ගොනුවක් වැනි වස්තුවක් ඔබට ලබා දෙනවා හැර , ඒ දේම කරයි . අයි / ඕ තරමක් වෙනස් ලෙස හැසිරවිය හැකි තවත් පොපන් ප්රභේද 3 ක් ඇත. ඔබ සෑම දෙයක්ම නූල් ලෙස සම්මත කරන්නේ නම්, එවිට ඔබේ විධානය කවචයට යවනු ලැබේ; ඔබ ඒවා ලැයිස්තුවක් ලෙස සම්මත කළහොත් කිසිවක් මග හැරීම ගැන කරදර විය යුතු නැත. ප්රලේඛනය බලන්න .
මෙම Popen
පන්ති subprocess
මොඩියුලය. මෙය ආදේශකයක් ලෙස අදහස් කරන os.popen
නමුත් එතරම් පුළුල් වීම නිසා තරමක් සංකීර්ණ වීමේ අවාසිය ඇත. උදාහරණයක් ලෙස, ඔබ මෙසේ කියයි:
print subprocess.Popen("echo Hello World", shell=True, stdout=subprocess.PIPE).stdout.read()
වෙනුවට:
print os.popen("echo Hello World").read()
නමුත් විවිධ විකල්පයන් 4 ක් වෙනුවට එක් විකල්ප පන්තියක ඇති සියලුම විකල්ප තිබීම සතුටක්. ප්රලේඛනය බලන්න .
මෙම call
සිට උත්සවය subprocess
මොඩියුලය. මෙය මූලික වශයෙන් Popen
පංතියට සමාන වන අතර එකම තර්ක සියල්ලම ගනී, නමුත් එය සරලවම විධානය සම්පූර්ණ වී ඔබට ආපසු කේතය ලබා දෙන තෙක් බලා සිටී. උදාහරණයක් වශයෙන්:
return_code = subprocess.call("echo Hello World", shell=True)
ප්රලේඛනය බලන්න .
ඔබ පයිතන් 3.5 හෝ ඊට පසු නම්, ඔබට නව subprocess.run
ශ්රිතය භාවිතා කළ හැකිය , එය ඉහත හා සමාන නමුත් වඩා නම්යශීලී වන CompletedProcess
අතර විධානය ක්රියාත්මක කිරීමෙන් පසු වස්තුවක් ආපසු ලබා දේ .
ඕඑස් මොඩියුලයට සී වැඩසටහනක ඔබ සතුව ඇති සියලුම දෙබලක / ක්රියාත්මක / ස්පොන් ශ්රිත ඇත, නමුත් ඒවා කෙලින්ම භාවිතා කිරීම මම නිර්දේශ නොකරමි.
මෙම subprocess
මොඩියුලය, සමහර විට ඔබ භාවිතා දේ විය යුතු ය.
අවසාන වශයෙන් කරුණාකර මතක තබා ගන්න ඔබ අවසාන විධානය සම්මත කරන සියලුම ක්රම සඳහා කවචය නූලක් ලෙස ක්රියාත්මක කළ යුතු අතර එයින් ගැලවීමට ඔබ වගකිව යුතුය. ඔබ පසුකර යන නූලෙහි කිසියම් කොටසක් සම්පූර්ණයෙන් විශ්වාස කළ නොහැකි නම් බරපතල ආරක්ෂක ඇඟවුම් තිබේ. උදාහරණයක් ලෙස, පරිශීලකයෙකු නූල් වල යම් / යම් කොටසක් ඇතුළත් කරන්නේ නම්. ඔබට සැක සහිත නම්, නියතයන් සමඟ පමණක් මෙම ක්රම භාවිතා කරන්න. ඇඟවුම් පිළිබඳ ඉඟියක් ඔබට ලබා දීමට මෙම කේතය සලකා බලන්න:
print subprocess.Popen("echo %s " % user_input, stdout=PIPE).stdout.read()
මුළු ගොනු පද්ධතියම මකා දැමිය හැකි "මගේ අම්මා මට ආදරය කළේ නැත && rm -rf /" යනුවෙන් පරිශීලකයා ඇතුළු වන බව සිතන්න.
open
.
subprocess.run()
. docs.python.org/3.5/library/subprocess.html#subprocess.run
subprocess.run(..)
, හරියටම කරන්නේ කුමක්ද "මෙය පෙරනිමියෙන් stdout හෝ stderr අල්ලා නොගනී." ඇඟවුම් කරන්නේ? subprocess.check_output(..)
STDERR ගැන කුමක් කිව හැකිද?
echo
සම්මත වැල ඉදිරිපිට Popen
? එබැවින් සම්පූර්ණ විධානය වනු ඇත echo my mama didnt love me && rm -rf /
.
subprocess.run()
හෝ එහි වැඩිමහල් සහෝදර සහෝදරියන් පමණි subprocess.check_call()
. මේවා ප්රමාණවත් නොවන අවස්ථා සඳහා බලන්න subprocess.Popen()
. os.popen()
සමහර විට කිසිසේත් සඳහන් නොකළ යුතුය, නැතහොත් "ඔබේම දෙබලක / exec / spawn කේතය හැක් කිරීමෙන් පසුව" පැමිණිය යුතුය.
සාමාන්ය ක්රියාත්මක කිරීම:
import subprocess
p = subprocess.Popen('ls', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in p.stdout.readlines():
print line,
retval = p.wait()
stdout
පයිප්පයේ ඇති දත්ත සමඟ ඔබට අවශ්ය දේ කිරීමට ඔබට නිදහස තිබේ . ඇත්ත වශයෙන්ම, ඔබට එම පරාමිතීන් ( stdout=
සහ stderr=
) අතහැර දැමිය හැකි අතර එය හැසිරෙනු os.system()
ඇත.
.readlines()
සියලුම රේඛා එකවර කියවයි , එනම් උප ක්රියාවලිය පිටවන තුරු එය අවහිර වේ (පයිප්පයේ අවසානය වසා දමයි). තථ්ය කාලීනව කියවීමට ( for line in iter(p.stdout.readline, ''): print line,
p.stdout.readline()
(සටහන: s
අවසානයේ නැත) දරුවා එහි බෆරය පුරවන තුරු කිසිදු දත්තයක් නොපෙනේ. දරුවා වැඩි දත්ත ප්රමාණයක් නිෂ්පාදනය නොකරන්නේ නම් ප්රතිදානය තත්ය වේලාවට නොලැබේ. Q හි දෙවන හේතුව බලන්න : පයිප්පයක් (පොපන් ()) භාවිතා නොකරන්නේ ඇයි? . මෙම පිළිතුරෙහි සමහර ක්රියාමාර්ග ලබා දී ඇත (pexpect, pty, stdbuf)
Popen
සරල කාර්යයන් සඳහා නිර්දේශ නොකළ යුතුය . මෙයද අනවශ්ය ලෙස නියම shell=True
කරයි. subprocess.run()
පිළිතුරු වලින් එකක් උත්සාහ කරන්න .
ඇමතුම් අංකයෙන් ළමා ක්රියාවලිය වෙන් කිරීම පිළිබඳ සමහර ඉඟි (ළමා ක්රියාවලිය පසුබිමෙන් ආරම්භ කිරීම).
ඔබට සීජීඅයි ස්ක්රිප්ට් එකකින් දිගු කාර්යයක් ආරම්භ කිරීමට අවශ්ය යැයි සිතමු. එනම්, ළමා ක්රියාවලිය සීජීඅයි ස්ක්රිප්ට් ක්රියාත්මක කිරීමේ ක්රියාවලියට වඩා දිගු කාලයක් ජීවත් විය යුතුය.
උපප්රොසෙස් මොඩියුලයේ ප්රලේඛනයෙන් සම්භාව්ය උදාහරණය:
import subprocess
import sys
# Some code here
pid = subprocess.Popen([sys.executable, "longtask.py"]) # Call subprocess
# Some more code here
මෙහි අදහස නම් longtask.py අවසන් වන තුරු 'ඇමතුම් උපසිරැසි' පේළියේ රැඳී සිටීමට ඔබට අවශ්ය නැති බවයි. නමුත් උදාහරණයෙන් 'මෙහි තවත් කේත කිහිපයක්' පේළියෙන් පසුව කුමක් සිදුවේද යන්න පැහැදිලි නැත.
මගේ ඉලක්ක වේදිකාව වූයේ ෆ්රීබීඑස්ඩී ය, නමුත් සංවර්ධනය වින්ඩෝස් මත විය, එබැවින් මම මුලින්ම වින්ඩෝස් හි ගැටලුවට මුහුණ දුන්නෙමි.
වින්ඩෝස් (වින්ඩෝස් එක්ස්පී) හි, longtask.py එහි වැඩ අවසන් වන තුරු මව් ක්රියාවලිය අවසන් නොවේ. එය සීජීඅයි ස්ක්රිප්ට් එකක ඔබට අවශ්ය දේ නොවේ. ගැටළුව පයිතන්ට විශේෂිත නොවේ; PHP ප්රජාව තුළ ගැටළු එක හා සමානයි.
විසඳුම වන්නේ වින්ඩෝස් ඒපීඅයි හි යටින් පවතින CreateProcess ශ්රිතයට DETACHED_PROCESS ක්රියාවලි නිර්මාණය කිරීමේ ධජය යැවීමයි. ඔබ pywin32 ස්ථාපනය කර ඇත්නම්, ඔබට win32process මොඩියුලයෙන් ධජය ආනයනය කළ හැකිය, එසේ නොමැතිනම් ඔබ එයම නිර්වචනය කළ යුතුය:
DETACHED_PROCESS = 0x00000008
pid = subprocess.Popen([sys.executable, "longtask.py"],
creationflags=DETACHED_PROCESS).pid
/ * UPD 2015.10.27 @eryksun පහත දැක්වෙන සටහනක, අර්ථ නිරූපණය නිවැරදි ධජය CREATE_NEW_CONSOLE (0x00000010) * /
FreeBSD හි අපට තවත් ගැටළුවක් ඇත: මව් ක්රියාවලිය අවසන් වූ විට, එය ළමා ක්රියාවලීන් ද අවසන් කරයි. සීජීඅයි ස්ක්රිප්ට් එකක ඔබට අවශ්ය වන්නේ එය නොවේ. සමහර අත්හදා බැලීම්වලින් පෙනී ගියේ ගැටළුව sys.stdout බෙදා ගැනීමේදී ඇති බවයි. වැඩ කරන විසඳුම පහත දැක්වේ:
pid = subprocess.Popen([sys.executable, "longtask.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
මම වෙනත් වේදිකාවල කේතය පරික්ෂා කර නැති අතර FreeBSD හි හැසිරීමට හේතු නොදනිමි. යමෙක් දන්නේ නම්, කරුණාකර ඔබේ අදහස් බෙදා ගන්න. පයිතන්හි පසුබිම් ක්රියාවලීන් ආරම්භ කිරීම පිළිබඳ ගූගල් කිරීම තවමත් කිසිදු ආලෝකයක් නොදක්වයි.
DETACHED_PROCESS
තුළ creationflags
කොන්සෝලයක් උරුම හෝ නිර්මාණය සිට දරුවා වැළැක්වීම මගින් වැලකී සිටීමේ මෙම. ඔබට ඒ වෙනුවට නව කොන්සෝලයක් අවශ්ය නම් CREATE_NEW_CONSOLE
(0x00000010) භාවිතා කරන්න .
os.devnull
සමහර කොන්සෝල වැඩසටහන් වෙනත් ආකාරයකින් දෝෂයකින් පිටවන නිසා ය. දෙමව්පියන්ගේ ක්රියාවලියට සමගාමීව ළමා ක්රියාවලිය පරිශීලකයා සමඟ අන්තර් ක්රියා කිරීමට අවශ්ය විට නව කොන්සෝලයක් සාදන්න. දෙකම එකම කවුළුවකින් කිරීමට උත්සාහ කිරීම ව්යාකූල වනු ඇත.
import os
os.system("your command")
විධානය පිරිසිදු කර නොමැති බැවින් මෙය භයානක බව සලකන්න. 'Os' සහ 'sys' මොඩියුලවල අදාළ ලියකියවිලි සඳහා ගූගල් කිරීමට මම ඔබට භාර දෙමි. ඒ හා සමාන දේවල් කරන කාර්යයන් සමූහයක් (exec * සහ spawn *) ඇත.
subprocess
තරමක් වැඩි හා අතේ ගෙන යා හැකි විසඳුමක් ලෙස පෙන්වා දිය යුතුය . බාහිර විධානයන් ක්රියාත්මක කිරීම ඇත්තෙන්ම සහජයෙන්ම කළ නොහැකි ය (ඔබට සහාය වීමට අවශ්ය සෑම ගෘහ නිර්මාණ ශිල්පයකම විධානය ලබා ගත හැකි බවට ඔබ සහතික විය යුතුය) සහ පරිශීලක ආදානය බාහිර විධානයක් ලෙස යැවීම සහජයෙන්ම අනාරක්ෂිත ය.
මම භාවිතා නිර්දේශ කරනවා subprocess එය ෂෙල් ඔබ වෙනුවෙන් මිදීමේ හා ඒ නිසා බොහෝ ආරක්ෂිත වීම නිසා ද os.system වෙනුවට මොඩියුලය.
subprocess.call(['ping', 'localhost'])
subprocess
විට shell=False
එවකට භාවිතා කරන්න, shlex.split
මෙය කිරීමට පහසු ක්රමයක් සඳහා docs.python.org/2/library/shlex.html#shlex.split ( docs docs.python.org/2/library/subprocess.html#popen-constructor අනුව එය නිර්දේශිත ක්රමයයි )
import os
cmd = 'ls -al'
os.system(cmd)
ඔබට විධානයේ ප්රති results ල ලබා දීමට අවශ්ය නම්, ඔබට භාවිතා කළ හැකිය os.popen
. කෙසේ වෙතත්, උපප්රොසෙස් මොඩියුලයට පක්ෂව 2.6 අනුවාදයේ සිට මෙය ඉවත් කර ඇති අතර අනෙක් පිළිතුරු හොඳින් ආවරණය වී ඇත.
පයිතන් සමඟ බාහිර විධාන ඇමතීමට ඔබට ඉඩ සලසන විවිධ පුස්තකාල රාශියක් ඇත. සෑම පුස්තකාලයක් සඳහාම මම විස්තරයක් ලබා දී බාහිර විධානයක් ඇමතීමේ උදාහරණයක් පෙන්වා ඇත. මම උදාහරණයක් ලෙස භාවිතා කළ විධානය නම් ls -l
(සියලුම ගොනු ලැයිස්තුගත කරන්න). මා ලැයිස්තුගත කර ඇති ඕනෑම පුස්තකාලයක් ගැන වැඩි විස්තර දැන ගැනීමට ඔබට අවශ්ය නම්, ඒ සෑම එකක් සඳහාම ලියකියවිලි සම්බන්ධ කර ඇත.
මුලාශ්ර:
මේ සියල්ල පුස්තකාල:
කුමන පුස්තකාලය භාවිතා කළ යුතුද යන්න පිළිබඳව තීරණයක් ගැනීමට මෙය ඔබට උපකාරී වනු ඇතැයි අපේක්ෂා කරමු :)
උප ක්රියාවලිය
උපසිරැසිය මඟින් ඔබට බාහිර විධානයන් ඇමතීමට සහ ඒවායේ ආදාන / ප්රතිදාන / දෝෂ පයිප්ප (stdin, stdout, සහ stderr) සමඟ සම්බන්ධ කිරීමට ඉඩ ලබා දේ. විධාන ක්රියාත්මක කිරීම සඳහා සුපුරුදු තේරීම උපප්රොසෙස් වේ, නමුත් සමහර විට වෙනත් මොඩියුලයන් වඩා හොඳය.
subprocess.run(["ls", "-l"]) # Run command
subprocess.run(["ls", "-l"], stdout=subprocess.PIPE) # This will run the command and return any output
subprocess.run(shlex.split("ls -l")) # You can also use the shlex library to split the command
os
os භාවිතා කරනුයේ "මෙහෙයුම් පද්ධති මත යැපෙන ක්රියාකාරිත්වය" සඳහා ය. os.system
සහ බාහිර විධාන ඇමතීමට ද මෙය භාවිතා කළ හැකිය os.popen
(සටහන: උපප්රොසෙස්.පොපන් ද ඇත). os සෑම විටම කවචය ධාවනය කරනු ඇති අතර එය අවශ්ය නොවන හෝ භාවිතා කිරීමට නොදන්නා අයට සරල විකල්පයකි subprocess.run
.
os.system("ls -l") # run command
os.popen("ls -l").read() # This will run the command and return any output
sh
sh යනු උප ක්රියාදාම අතුරුමුහුණතක් වන අතර එමඟින් වැඩසටහන් ක්රියාකාරී ලෙස හැඳින්වීමට ඔබට ඉඩ සලසයි. ඔබට කිහිප වතාවක් විධානයක් ක්රියාත්මක කිරීමට අවශ්ය නම් මෙය ප්රයෝජනවත් වේ.
sh.ls("-l") # Run command normally
ls_cmd = sh.Command("ls") # Save command as a variable
ls_cmd() # Run command as if it were a function
ප්ලම්බම්
plumbum යනු "ස්ක්රිප්ට් වැනි" පයිතන් වැඩසටහන් සඳහා පුස්තකාලයකි. ඔබට වැනි කාර්යයන් වැනි වැඩසටහන් ඇමතිය හැකිය sh
. ඔබට කවචය නොමැතිව නල මාර්ගයක් ධාවනය කිරීමට අවශ්ය නම් ප්ලම්බම් ප්රයෝජනවත් වේ.
ls_cmd = plumbum.local("ls -l") # get command
ls_cmd() # run command
pexpect
ළමා යෙදුම් බිහි කිරීමට, ඒවා පාලනය කිරීමට සහ ඒවායේ ප්රතිදානයේ රටා සොයා ගැනීමට pexpect ඔබට ඉඩ දෙයි. යුනික්ස් හි tty එකක් අපේක්ෂා කරන විධාන සඳහා උපප්රොසෙස් සඳහා මෙය වඩා හොඳ විකල්පයකි.
pexpect.run("ls -l") # Run command as normal
child = pexpect.spawn('scp foo user@example.com:.') # Spawns child application
child.expect('Password:') # When this is the output
child.sendline('mypassword')
රෙදි
රෙදි යනු පයිතන් 2.5 සහ 2.7 පුස්තකාලයකි. දේශීය සහ දුරස්ථ ෂෙල් විධාන ක්රියාත්මක කිරීමට එය ඔබට ඉඩ සලසයි. ආරක්ෂිත කවචයක (SSH) විධාන ක්රියාත්මක කිරීම සඳහා රෙදි සරල විකල්පයකි
fabric.operations.local('ls -l') # Run command as normal
fabric.operations.local('ls -l', capture = True) # Run command and receive output
තානාපති
තානාපතිවරයා "මිනිසුන් සඳහා උප ක්රියාවලිය" ලෙස හැඳින්වේ. එය subprocess
මොඩියුලය වටා පහසුව සඳහා වන ආවරණයක් ලෙස භාවිතා කරයි .
r = envoy.run("ls -l") # Run command
r.std_out # get output
විධාන
commands
සඳහා එතීමේ කාර්යයන් අඩංගු වේ os.popen
, නමුත් එතැන් සිට එය පයිතන් 3 වෙතින් ඉවත් කර ඇතsubprocess
වඩා හොඳ විකල්පයක් එය .
සංස්කරණය පදනම් වූයේ ජේ. එෆ්. සෙබස්තියන්ගේ ප්රකාශය මත ය.
මම සෑම විටම fabric
මේ වගේ දේවල් සඳහා භාවිතා කරමි :
from fabric.operations import local
result = local('ls', capture=True)
print "Content:/n%s" % (result, )
නමුත් මෙය හොඳ මෙවලමක් ලෙස පෙනේ: sh
(පයිතන් උප සැකසුම් අතුරුමුහුණත) .
උදාහරණයක් බලන්න:
from sh import vgdisplay
print vgdisplay()
print vgdisplay('-v')
print vgdisplay(v=True)
"Pexpect" පයිතන් පුස්තකාලයද පරීක්ෂා කරන්න.
බාහිර වැඩසටහන් / විධාන, ssh, ftp, telnet යනාදිය අන්තර්ක්රියාකාරී ලෙස පාලනය කිරීමට එය ඉඩ දෙයි. ඔබට මෙවැනි දෙයක් ටයිප් කළ හැකිය:
child = pexpect.spawn('ftp 192.168.0.24')
child.expect('(?i)name .*: ')
child.sendline('anonymous')
child.expect('(?i)password')
උප සැකසුම් මොඩියුලය භාවිතා කරන්න (පයිතන් 3):
import subprocess
subprocess.run(['ls', '-l'])
එය නිර්දේශිත සම්මත ක්රමයයි. කෙසේ වෙතත්, වඩාත් සංකීර්ණ කාර්යයන් (පයිප්ප, ප්රතිදානය, ආදානය, ආදිය) තැනීමට හා ලිවීමට වෙහෙසකාරී විය හැකිය.
Python අනුවාදය පිළිබඳ සටහන: ඔබ තවමත් Python 2 භාවිතා කරන්නේ නම්, subprocess.call සමාන ආකාරයකින් ක්රියා කරයි.
ProTip: shlex.split ඔබ විධාන පේළියේ කිරීමට උපකාර කළ හැකි run
, call
සහ වෙනත් subprocess
(! හෝ ඔබට නොහැකි) ඔබට අවශ්ය නැහැ නඩුවේ කටයුතු ලැයිස්තු ස්වරූපයෙන් ඔවුන් ලබා:
import shlex
import subprocess
subprocess.run(shlex.split('ls -l'))
බාහිර පරායත්තතාවයන් ඔබට ප්රශ්නයක් නොවේ නම්, ප්ලම්බම් භාවිතා කරන්න :
from plumbum.cmd import ifconfig
print(ifconfig['wlan0']())
එය හොඳම subprocess
එතුමයි. එය හරස් වේදිකාවකි, එනම් එය වින්ඩෝස් සහ යුනික්ස් වැනි පද්ධති දෙකෙහිම ක්රියා කරයි. විසින් ස්ථාපනය කරන්නpip install plumbum
.
තවත් ජනප්රිය පුස්තකාලයක් වන්නේ sh :
from sh import ifconfig
print(ifconfig('wlan0'))
කෙසේ වෙතත්, sh
වින්ඩෝස් සහාය අතහැර දැමූ නිසා එය පෙර මෙන් භයානක නොවේ. විසින් ස්ථාපනය කරන්න pip install sh
.
ඔබ කතා කරන්නේ විධානය සිට ප්රතිදානය අවශ්ය නම්, ඔබ භාවිතා කළ හැකිය subprocess.check_output (Python 2.7+).
>>> subprocess.check_output(["ls", "-l", "/dev/null"])
'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n'
ෂෙල් පරාමිතිය ද සටහන් කරන්න .
කවචය නම්
True
, නිශ්චිත විධානය කවචය හරහා ක්රියාත්මක වේ. ඔබ බොහෝ විට පද්ධති ෂෙල් වලට වඩා වැඩි දියුණු කරන ලද පාලන ප්රවාහයක් සඳහා පයිතන් භාවිතා කරන්නේ නම් මෙය ප්රයෝජනවත් විය හැකි අතර ෂෙල් පයිප්ප, ගොනු නාම ආදේශක කාඩ්පත්, පරිසර විචල්ය ප්රසාරණය සහ පරිශීලක නිවසකට ~ පුළුල් කිරීම වැනි වෙනත් ෂෙල් අංග වෙත පහසුවෙන් ප්රවේශ වීමට අවශ්ය නම්. නාමාවලිය. කෙසේ වෙතත්, Python ම (විශේෂයෙන් ම, බොහෝ ෂෙල් වැනි ලක්ෂණ නිර්මාණයන් විසින් ලබා දී ඇති බව සටහන්glob
,fnmatch
,os.walk()
,os.path.expandvars()
,os.path.expanduser()
, සහshutil
).
check_output
වඩා ලැයිස්තුවක් අවශ්ය බව සලකන්න . ඔබගේ ඇමතුම වලංගු කිරීම සඳහා ඔබ උපුටා ගත් අවකාශයන් මත රඳා නොසිටින්නේ නම්, මෙය කිරීමට සරලම, වඩාත්ම කියවිය හැකි ක්රමය වේ subprocess.check_output("ls -l /dev/null".split())
.
මම මගේ විධාන ක්රියාත්මක කරන්නේ එලෙසයි. මෙම කේතයේ ඔබට අවශ්ය සෑම දෙයක්ම තිබේ
from subprocess import Popen, PIPE
cmd = "ls -l ~/"
p = Popen(cmd , shell=True, stdout=PIPE, stderr=PIPE)
out, err = p.communicate()
print "Return code: ", p.returncode
print out.rstrip(), err.rstrip()
subprocess.run
ඔබේ කේතයට පෙර පයිතන් අනුවාද සමඟ අනුකූලතාව පවත්වා ගැනීමට අවශ්ය නොවන්නේ නම් පයිතන් 3.5 හි නිර්දේශිත ප්රවේශය වේ. එය වඩාත් ස්ථාවර වන අතර තානාපතිවරයාට සමාන භාවිතයේ පහසුවක් ලබා දෙයි. (පයිප්ප දැමීම එතරම් සරල නැත. කෙසේ දැයි මෙම ප්රශ්නය බලන්න .)
මෙන්න ප්රලේඛනයෙන් උදාහරණ කිහිපයක් .
ක්රියාවලියක් ක්රියාත්මක කරන්න:
>>> subprocess.run(["ls", "-l"]) # Doesn't capture output
CompletedProcess(args=['ls', '-l'], returncode=0)
අසාර්ථක ධාවනයේ නැගීම:
>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
අල්ලා ගැනීමේ ප්රතිදානය:
>>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE)
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,
stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n')
තානාපති උත්සාහ කිරීමට මම නිර්දේශ කරමි . එය උපසිරැසි සඳහා එතීමකි, එමඟින් පැරණි මොඩියුල සහ කාර්යයන් ප්රතිස්ථාපනය කිරීම අරමුණු කරයි . තානාපති යනු මිනිසුන් සඳහා උප ක්රියාවලියකි.
README වෙතින් උදාහරණ භාවිතය :
>>> r = envoy.run('git config', data='data to pipe in', timeout=2)
>>> r.status_code
129
>>> r.std_out
'usage: git config [options]'
>>> r.std_err
''
පයිප්ප දේවල් ද වටේ:
>>> r = envoy.run('uptime | pbcopy')
>>> r.command
'pbcopy'
>>> r.status_code
0
>>> r.history
[<Response 'uptime'>]
os.system
හරි, නමුත් යම් ආකාරයක දින වකවානු. එය ද ඉතා ආරක්ෂිත නොවේ. ඒ වෙනුවට, උත්සාහ කරන්න subprocess
. subprocess
කෙලින්ම sh අමතන්නේ නැති අතර එම නිසා වඩා ආරක්ෂිත වේos.system
.
වැඩි විස්තර මෙතැනින් ලබා ගන්න .
subprocess
සියලු ආරක්ෂක ගැටළු ඉවත් නොකරයි, සහ තමන්ගේම ගැටළු කිහිපයක් තිබේ.
පයිතන්හි බාහිර විධානයක් ඇමතීම
වස්තුවක් subprocess.run
ආපසු ලබා දෙන සරල, භාවිතා කරන්න CompletedProcess
:
>>> import subprocess
>>> completed_process = subprocess.run('python --version')
Python 3.6.1 :: Anaconda 4.4.0 (64-bit)
>>> completed_process
CompletedProcess(args='python --version', returncode=0)
පයිතන් 3.5 වන විට, ප්රලේඛනය උපප්රොසෙස් නිර්දේශ කරයි :
උපසිරැසි ක්රියාත්මක කිරීම සඳහා නිර්දේශිත ප්රවේශය නම්, එය හැසිරවිය හැකි සියළුම භාවිත අවස්ථා සඳහා ධාවන () ශ්රිතය භාවිතා කිරීමයි. වඩාත් දියුණු භාවිත අවස්ථා සඳහා, යටින් පවතින පොපන් අතුරුමුහුණත කෙලින්ම භාවිතා කළ හැකිය.
හැකි සරලම භාවිතයට උදාහරණයක් මෙන්න - එය ඉල්ලූ ආකාරයටම කරයි:
>>> import subprocess
>>> completed_process = subprocess.run('python --version')
Python 3.6.1 :: Anaconda 4.4.0 (64-bit)
>>> completed_process
CompletedProcess(args='python --version', returncode=0)
run
විධානය සාර්ථකව අවසන් වන තෙක් බලා සිට පසුව CompletedProcess
වස්තුවක් ලබා දෙයි. එය ඒ වෙනුවට මතු කළ හැකියTimeoutExpired
(ඔබ එයට timeout=
තර්කයක් දුන්නොත් ) හෝ CalledProcessError
(එය අසමත් වී ඔබ සමත් වුවහොත් check=True
).
ඉහත උදාහරණයෙන් ඔබ අනුමාන කළ හැකි පරිදි, stdout සහ stderr යන දෙකම පෙරනිමියෙන් ඔබේම stdout සහ stderr වෙත නල ලබා ගනී.
අපට ආපසු ලබා දුන් වස්තුව පරීක්ෂා කර ලබා දී ඇති විධානය සහ ආපසු කේතය බලන්න:
>>> completed_process.args
'python --version'
>>> completed_process.returncode
0
ඔබට ප්රතිදානය ග්රහණය කර ගැනීමට අවශ්ය නම්, ඔබට subprocess.PIPE
සුදුසු stderr
හෝ stdout
:
>>> cp = subprocess.run('python --version',
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
>>> cp.stderr
b'Python 3.6.1 :: Anaconda 4.4.0 (64-bit)\r\n'
>>> cp.stdout
b''
(අනුවාදයේ තොරතුරු stdout වෙනුවට stderr වෙත ලබා දීම සිත්ගන්නාසුළු හා තරමක් ප්රතිවිරුද්ධ බව මට පෙනේ.)
අණ දාමයක් අතින් ලබා දීමෙන් (ප්රශ්නය යෝජනා කරන පරිදි) ක්රමලේඛයෙන් සාදන ලද නූලක් සැපයීම දක්වා යමෙකුට පහසුවෙන් ගමන් කළ හැකිය. ක්රමලේඛිකව නූල් සාදන්න එපා. මෙය විභව ආරක්ෂක ගැටළුවක්. ඔබ ආදානය විශ්වාස නොකරයි යැයි සිතීම වඩා හොඳය.
>>> import textwrap
>>> args = ['python', textwrap.__file__]
>>> cp = subprocess.run(args, stdout=subprocess.PIPE)
>>> cp.stdout
b'Hello there.\r\n This is indented.\r\n'
සටහන, ස්ථානීයව පමණක් args
සම්මත කළ යුතුය.
ප්රභවයේ සත්ය අත්සන මෙන්න සහ පෙන්වා ඇති පරිදි help(run)
:
def run(*popenargs, input=None, timeout=None, check=False, **kwargs):
මෙම popenargs
සහ kwargs
වෙත ලබා දී ඇත Popen
ඉදිකිරීමටත්. input
බයිට් මාලාවක් විය හැකිය (හෝ යුනිකෝඩ්, කේතන ක්රමයක් සඳහන් කරන්නේ නම් හෝ universal_newlines=True
) එය උපසිරැසි ස්ටැඩින් වෙත නල කරනු ලැබේ.
ප්රලේඛනය විස්තර කරන timeout=
අතර check=True
මට වඩා හොඳය:
කල් ඉකුත් වීමේ තර්කය Popen.communicate () වෙත යවනු ලැබේ. කල් ඉකුත් වීම කල් ඉකුත්වුවහොත්, ළමා ක්රියාවලිය මරා දමා බලා සිටිනු ඇත. ළමා ක්රියාවලිය අවසන් වූ පසු කල් ඉකුත් වූ ව්යතිරේකය නැවත මතු කරනු ඇත.
චෙක්පත සත්ය නම්, සහ ක්රියාවලිය ශුන්ය නොවන පිටවීමේ කේතයක් සමඟ පිටවන්නේ නම්, කැල්ඩ්ප්රොසෙස්රෙරර් ව්යතිරේකයක් මතු වේ. එම ව්යතිරේකයේ ගුණාංග තර්ක, පිටවීමේ කේතය සහ ඒවා අල්ලා ගනු ලැබුවේ නම් stdout සහ stderr ය.
මෙම උදාහරණය check=True
මට ඉදිරිපත් කළ හැකි එකකට වඩා හොඳය:
>>> subprocess.run("exit 1", shell=True, check=True) Traceback (most recent call last): ... subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
ප්රලේඛනයේ දක්වා ඇති පරිදි පුළුල් අත්සනක් මෙන්න:
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None)
මෙයින් ඇඟවෙන්නේ ආග්ස් ලැයිස්තුව පමණක් ස්ථානගතව සම්මත කළ යුතු බවයි. එබැවින් ඉතිරි තර්ක යතුරු පද තර්ක ලෙස සම්මත කරන්න.
Popen
ඒ වෙනුවට භාවිතා කරන්නේ කවදාද? තර්ක මත පමණක් පදනම්ව භාවිත අවස්ථා සොයා ගැනීමට මම වෙහෙසෙමි. Popen
කෙසේ වෙතත්, සෘජුවම භාවිතා කිරීම ඇතුළුව, එහි ක්රම වලට ප්රවේශය ලබා දේpoll
'send_signal', 'අවසන් කිරීම' සහ 'රැඳී සිටීම' .
මූලාශ්රයේPopen
දක්වා ඇති පරිදි අත්සන මෙන්න . මම හිතන්නේ මෙය වඩාත් නිවැරදිව තොරතුරු සංයුක්ත කිරීමකි (ඊට වෙනස්ව help(Popen)
):
def __init__(self, args, bufsize=-1, executable=None,
stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS,
shell=False, cwd=None, env=None, universal_newlines=False,
startupinfo=None, creationflags=0,
restore_signals=True, start_new_session=False,
pass_fds=(), *, encoding=None, errors=None):
එහෙත් වඩා තොරතුරු වේ ද Popen
ප්රලේඛනය :
subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, encoding=None, errors=None)
නව ක්රියාවලියක ළමා වැඩසටහනක් ක්රියාත්මක කරන්න. POSIX හි, ළමා වැඩසටහන ක්රියාත්මක කිරීම සඳහා පන්තිය os.execvp () භාවිතා කරයි. වින්ඩෝස් හි, පන්තිය වින්ඩෝස් ක්රියේට් ප්රොසෙස් () ශ්රිතය භාවිතා කරයි. පොපන් සඳහා වන තර්ක පහත පරිදි වේ.
ඉතිරි ලියකියවිලි තේරුම් ගැනීම පා er කයාට Popen
අභ්යාසයක් ලෙස ඉතිරි වේ.
shell=True
විධානය ලැයිස්තුවක් ලෙස තිබිය යුතුය .
>>> from plumbum import local
>>> ls = local["ls"]
>>> ls
LocalCommand(<LocalPath /bin/ls>)
>>> ls()
u'build.py\ndist\ndocs\nLICENSE\nplumbum\nREADME.rst\nsetup.py\ntests\ntodo.txt\n'
>>> notepad = local["c:\\windows\\notepad.exe"]
>>> notepad() # Notepad window pops up
u'' # Notepad window is closed by user, command returns
භාවිත:
import os
cmd = 'ls -al'
os.system(cmd)
os - මෙම මොඩියුලය මෙහෙයුම් පද්ධති මත යැපෙන ක්රියාකාරීත්වය භාවිතා කළ හැකි අතේ ගෙන යා හැකි ක්රමයක් සපයයි.
වැඩි os
කාර්යයන් සඳහා, මෙන්න ප්රලේඛනය.
එය මෙය සරල විය හැකිය:
import os
cmd = "your command"
os.system(cmd)
එහි සරල බව සඳහා මම shell_command ට කැමතියි . එය උපසිරැසි මොඩියුලය මත ගොඩනගා ඇත.
ප්රලේඛනයෙන් උදාහරණයක් මෙන්න:
>>> from shell_command import shell_call
>>> shell_call("ls *.py")
setup.py shell_command.py test_shell_command.py
0
>>> shell_call("ls -l *.py")
-rw-r--r-- 1 ncoghlan ncoghlan 391 2011-12-11 12:07 setup.py
-rw-r--r-- 1 ncoghlan ncoghlan 7855 2011-12-11 16:16 shell_command.py
-rwxr-xr-x 1 ncoghlan ncoghlan 8463 2011-12-11 16:17 test_shell_command.py
0
මෙහි කලින් සඳහන් නොකළ තවත් වෙනසක් තිබේ.
subprocess.Popen
<command> උප ක්රියාවලියක් ලෙස ක්රියාත්මක කරයි. මගේ නඩුවේදී, මට වෙනත් වැඩසටහනක් සමඟ සන්නිවේදනය කිරීමට අවශ්ය වන <a> ගොනුව ක්රියාත්මක කිරීමට අවශ්යයි, <b>.
මම උපසිරැසි උත්සාහ කළ අතර ක්රියාත්මක කිරීම සාර්ථක විය. කෙසේ වෙතත් <b> <a> සමඟ සන්නිවේදනය කිරීමට නොහැකි විය. මම ටර්මිනලයේ සිට දෙකම ධාවනය කරන විට සියල්ල සාමාන්යයි.
තවත් එකක්: (සටහන: kwrite වෙනත් යෙදුම් වලට වඩා වෙනස් ලෙස ක්රියා කරයි. ඔබ පහත දැක්වෙන්නේ ෆයර්ෆොක්ස් සමඟ උත්සාහ කළහොත් ප්රති results ල සමාන නොවේ.)
ඔබ උත්සාහ කරන්නේ නම් os.system("kwrite")
, පරිශීලකයා kwrite වැසෙන තුරු වැඩසටහන් ප්රවාහය කැටි වේ. එය ජය ගැනීම සඳහා මම ඒ වෙනුවට උත්සාහ කළෙමිos.system(konsole -e kwrite)
. මෙම කාල වැඩසටහන දිගටම ගලා ගිය නමුත් kwrite කොන්සෝලයේ උප ක්රියාවලිය බවට පත්විය.
ඕනෑම අයෙකු kwrite ධාවනය කරන්නේ උප ක්රියාවලියක් නොවේ (එනම් පද්ධති මොනිටරයේ එය ගසේ වම් කෙළවරේ දිස්විය යුතුය).
os.system
ප්රති results ල ගබඩා කිරීමට ඔබට ඉඩ නොදේ, එබැවින් ඔබට යම් ලැයිස්තුවක හෝ වෙනත් දෙයක ප්රති results ල ගබඩා කිරීමට අවශ්ය නම්, subprocess.call
ක්රියා කරයි.
භාවිතා කිරීමට මම නැඹුරු subprocess සමග එක්ව shlex (උපුටා නූල් පලා එන හැසිරවීමට):
>>> import subprocess, shlex
>>> command = 'ls -l "/your/path/with spaces/"'
>>> call_params = shlex.split(command)
>>> print call_params
["ls", "-l", "/your/path/with spaces/"]
>>> subprocess.call(call_params)
ලැජ්ජා විරහිත ප්ලග්, මම මේ සඳහා පුස්තකාලයක් ලිව්වෙමි: P https://github.com/houqp/shell.py
එය මූලික වශයෙන් දැනට පොපන් සහ ෂෙල්ක්ස් සඳහා එතුමකි. පයිතන් හි විධාන පහසුවෙන් සම්බන්ධ කර ගත හැකි වන පරිදි එය පයිප්ප විධාන සඳහාද සහාය වේ. එබැවින් ඔබට මෙවැනි දේ කළ හැකිය:
ex('echo hello shell.py') | "awk '{print $2}'"
වින්ඩෝස් හි ඔබට subprocess
මොඩියුලය ආයාත කර බාහිර විධාන ඇමතීමෙන් ක්රියාත්මක කළ හැකිය subprocess.Popen()
, subprocess.Popen().communicate()
සහ subprocess.Popen().wait()
පහත පරිදි:
# Python script to run a command line
import subprocess
def execute(cmd):
"""
Purpose : To execute a command and return exit status
Argument : cmd - command to execute
Return : exit_code
"""
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(result, error) = process.communicate()
rc = process.wait()
if rc != 0:
print "Error: failed to execute command:", cmd
print error
return result
# def
command = "tasklist | grep python"
print "This process detail: \n", execute(command)
ප්රතිදානය:
This process detail:
python.exe 604 RDP-Tcp#0 4 5,660 K
ලිනක්ස් යටතේ, ඔබ ස්වාධීනව ක්රියාත්මක වන බාහිර විධානයක් ඇමතීමට කැමති නම් (පයිතන් ස්ක්රිප්ට් අවසන් වූ පසු දිගටම ක්රියාත්මක වේ), ඔබට සරල පෝලිමක් කාර්ය ස්පූලර් ලෙස හෝ at command ලෙස භාවිතා කළ හැකිය.
කාර්ය ස්පූලර් සමඟ උදාහරණයක්:
import os
os.system('ts <your-command>')
කාර්ය ස්පූලර් ( ts
) පිළිබඳ සටහන් :
ක්රියාත්මක කළ යුතු සමගාමී ක්රියාවලි ගණන ("තව්") සමඟ ඔබට සැකසිය හැකිය:
ts -S <number-of-slots>
ස්ථාපනය කිරීමට ts
පරිපාලක වරප්රසාද අවශ්ය නොවේ. ඔබට එය මූලාශ්රයෙන් සරල ලෙස බාගත කර සම්පාදනය කළ හැකිය make
, එය ඔබේ මාර්ගයට එක් කරන්න.
ts
මා දන්නා ඕනෑම ඩිස්ට්රෝ එකක සම්මත නොවේ, නමුත් දර්ශකය at
සුළු වශයෙන් ප්රයෝජනවත් වේ. ඔබ බොහෝ විට සඳහන් කළ යුතුය batch
. වෙනත් තැනක මෙන්, os.system()
නිර්දේශයේ අවම වශයෙන් subprocess
එය නිර්දේශිත ආදේශනය බව සඳහන් කළ යුතුය .
OpenStack Neutron වෙතින් ජාල හැඳුනුම්පත ලබා ගැනීම සඳහා :
#!/usr/bin/python
import os
netid = "nova net-list | awk '/ External / { print $2 }'"
temp = os.popen(netid).read() /* Here temp also contains new line (\n) */
networkId = temp.rstrip()
print(networkId)
නෝවා ශුද්ධ ලැයිස්තුවේ ප්රතිදානය
+--------------------------------------+------------+------+
| ID | Label | CIDR |
+--------------------------------------+------------+------+
| 431c9014-5b5d-4b51-a357-66020ffbb123 | test1 | None |
| 27a74fcd-37c0-4789-9414-9531b7e3f126 | External | None |
| 5a2712e9-70dc-4b0e-9281-17e02f4684c9 | management | None |
| 7aa697f5-0e60-4c15-b4cc-9cb659698512 | Internal | None |
+--------------------------------------+------------+------+
මුද්රණයේ ප්රතිදානය (networkId)
27a74fcd-37c0-4789-9414-9531b7e3f126
os.popen()
2016 දී නිර්දේශ නොකළ යුතුය . අව්ක් ස්ක්රිප්ට් පහසුවෙන් දේශීය පයිතන් කේතය සමඟ ප්රතිස්ථාපනය කළ හැකිය.
echo $PATH
භාවිතාcall(["echo", "$PATH"])
, නමුත් එය හුදෙක් සාහිත්යමය string ප්රතිරාවය$PATH
ඕනෑම ආදේශන කරන්නේ වෙනුවට. මට PATH පරිසර විචල්යය ලබා ගත හැකි බව මම දනිමි, නමුත් විධානය හැසිරවීමට පහසු ක්රමයක් තිබේදැයි මම කල්පනා කරමි.