3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ハロウィンなのでPythonにほげほげさせてみる

Last updated at Posted at 2017-10-31

破壊的な処理をするわけでもないので、基本的には問題は生じないはずだが、一応。
註:この記事の内容はジョークです。生じた損害に対する責任は一切負いません。

前書き

Pythonのリファレンスをなんとなく読んでいると、次のような記述を見つけた。

sys.ps1 と sys.ps2 という変数は一次プロンプトと二次プロンプトに表示する文字列を定義しています:

>>>
>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = 'C> '
C> print('Yuck!')
Yuck!
C>

え、プロンプトのマークって置き換えられるの?これはもう、遊ぶしかない。

結論から言うと

結論から言うと、次のようないたずらをした。
いつもどおり対話環境を起動したらほげほげふがふがしているといういたずら。
hoge.jpg

コード

次のようなスクリプトを書いた。
このうちtrick_init.pyを実行すると、必要なファイルが生成される。

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()

exec_meta.py
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)
        )

べた書きべたべたの汚いコードだが、これを実行するとこれらのファイルが作られる。
(ところどころ個人情報を伏せている)

python.bat
@echo off
C:\ProgramData\Miniconda3\python.exe -i C:\...\trick_work\trick.py
exit /b

trick.py
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                                               

prompt.txt
hogeeeeeeeeeeeeeeeeeeeeeee 
fugaaaaaaaaaaaaaaaaaaaaaaa 

あとは、このpython.batを本物より参照優先度の高いところにおくだけ。

prompt.txtの内容は自由に書き換えることが出来る。
テキストエディタかなにかで適当に編集してみると面白いだろう。

また、自動生成こそされないが、message.txtを置くとその内容が利用される。
例えば、次のようにすると...

message.txt
-[------->+<]>.+[-->+<]>++.---[->+++<]>+.[->+++++<]>-.---[->++++<]>-.----.+++..+++++++.-[-->+++++<]>.------------.-[--->++<]>-.+++++++++++.+[--->+<]>.-[->+++<]>+.+[---->+<]>+++.[->+++<]>+.-[->+++<]>.-[--->++<]>.+++++.----.------.[->+++<]>-.>++++++++++.++[->++++++<]>.[--->++++<]>+.-[++>-----<]>..+++++++++.-[---->+<]>++.++++[->++<]>.[--->++++<]>+.+++++++++++..+++.++++++++.[->+++<]>..+++++++++.-[->+++++<]>.

hoge2.jpg

このように小洒落たメッセージが表示される。

遊び終わったら

python.batを消すだけ。そうすれば、もともとのPythonが使えるようになる。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?