破壊的な処理をするわけでもないので、基本的には問題は生じないはずだが、一応。
註:この記事の内容はジョークです。生じた損害に対する責任は一切負いません。
前書き
Pythonのリファレンスをなんとなく読んでいると、次のような記述を見つけた。
sys.ps1 と sys.ps2 という変数は一次プロンプトと二次プロンプトに表示する文字列を定義しています:
>>> >>> import sys >>> sys.ps1 '>>> ' >>> sys.ps2 '... ' >>> sys.ps1 = 'C> ' C> print('Yuck!') Yuck! C>
え、プロンプトのマークって置き換えられるの?これはもう、遊ぶしかない。
結論から言うと
結論から言うと、次のようないたずらをした。
いつもどおり対話環境を起動したらほげほげふがふがしているといういたずら。
コード
次のようなスクリプトを書いた。
このうちtrick_init.py
を実行すると、必要なファイルが生成される。
import sys, os
from exec_meta import get_info, do_cmd, write_lines_to_file
_DIR_PATH = os.path.dirname(os.path.abspath(__file__)) + r'\trick_work'
def make_fake_python():
real_python_path = get_info('where python')[0]
real_python_message = '\n'.join([
sys.version, 'Type "help", "copyright", "credits" or "license" for more information.'
])
write_lines_to_file(_DIR_PATH + r'\prompt.txt',
'hogeeeeeeeeeeeeeeeeeeeeeee ',
'fugaaaaaaaaaaaaaaaaaaaaaaa '
)
write_lines_to_file(_DIR_PATH + r'\trick.py',
'dir_path = r"{}" '.format(_DIR_PATH),
'with open(dir_path + r"\\prompt.txt", "r") as f: ',
' try: ',
' __import__("sys").ps1 = next(f).rstrip("\\n") ',
' __import__("sys").ps2 = next(f).rstrip("\\n") ',
' except: ',
' pass ',
' ',
'if __import__("os").path.isfile(dir_path + r"\\message.txt"): ',
' with open(dir_path + r"\\message.txt", "r") as f: ',
' print(f.read()) ',
'else: ',
' print("""\\\n{}""")' .format(real_python_message),
' ',
'del dir_path, f '
)
write_lines_to_file(_DIR_PATH + r'\python.bat',
'@echo off',
real_python_path + r' -i {}\trick.py'.format(_DIR_PATH),
'exit /b'
)
def main():
do_cmd('mkdir {} > NUL 2>&1'.format(_DIR_PATH), ignoring_error=True)
make_fake_python()
if __name__ == '__main__':
main()
from subprocess import check_output, check_call, call
def get_info(cmd, char_code='shift-jis'):
return [
b_line.decode(char_code).rstrip()
for b_line in check_output(cmd.split(), shell=True).split('\n'.encode(char_code))
if b_line
]
def do_cmd(cmd, *, ignoring_error=False):
if ignoring_error:
call(cmd, shell=True)
else:
check_call(cmd, shell=True)
def write_lines_to_file(file_path, *lines):
with open(file_path, 'w') as f:
f.writelines(
map(lambda x: x + '\n', lines)
)
べた書きべたべたの汚いコードだが、これを実行するとこれらのファイルが作られる。
(ところどころ個人情報を伏せている)
@echo off
C:\ProgramData\Miniconda3\python.exe -i C:\...\trick_work\trick.py
exit /b
dir_path = r"C:\...\trick_work"
with open(dir_path + r"\prompt.txt", "r") as f:
try:
__import__("sys").ps1 = next(f).rstrip("\n")
__import__("sys").ps2 = next(f).rstrip("\n")
except:
pass
if __import__("os").path.isfile(dir_path + r"\message.txt"):
with open(dir_path + r"\message.txt", "r") as f:
print(f.read())
else:
print("""\
3.6.0 |Continuum Analytics, Inc.| (default, Dec 23 2016, 11:57:41) [MSC v.1900 64 bit (AMD64)]
Type "help", "copyright", "credits" or "license" for more information.""")
del dir_path, f
hogeeeeeeeeeeeeeeeeeeeeeee
fugaaaaaaaaaaaaaaaaaaaaaaa
あとは、このpython.batを本物より参照優先度の高いところにおくだけ。
prompt.txtの内容は自由に書き換えることが出来る。
テキストエディタかなにかで適当に編集してみると面白いだろう。
また、自動生成こそされないが、message.txtを置くとその内容が利用される。
例えば、次のようにすると...
-[------->+<]>.+[-->+<]>++.---[->+++<]>+.[->+++++<]>-.---[->++++<]>-.----.+++..+++++++.-[-->+++++<]>.------------.-[--->++<]>-.+++++++++++.+[--->+<]>.-[->+++<]>+.+[---->+<]>+++.[->+++<]>+.-[->+++<]>.-[--->++<]>.+++++.----.------.[->+++<]>-.>++++++++++.++[->++++++<]>.[--->++++<]>+.-[++>-----<]>..+++++++++.-[---->+<]>++.++++[->++<]>.[--->++++<]>+.+++++++++++..+++.++++++++.[->+++<]>..+++++++++.-[->+++++<]>.
このように小洒落たメッセージが表示される。
遊び終わったら
python.batを消すだけ。そうすれば、もともとのPythonが使えるようになる。