操作系统如何运行程序

人和操作系统如何交互?最早Ken Thompson设计Unix的时候,使用的是命令解释器,命令解释器接受用户的命令,然后解释他们并执行。

Shell是人和机器交互的界面,分为GUI命令行(CLI)两种方式,这里重点介绍命令行的方式。概念Shell路易斯·普赞(Louis Pouzin)在1964年至1965年间首次提出,随后在Multics(MULTiplexed Information and Computing System)项目中首次被实现出来。肯·汤普逊(Ken Thompson)以Multics上的shell为范本实现的第一个Unix壳层(Unix shell):Thompson shell。AT&T贝尔实验室的史蒂夫·伯恩在1977年实现了Bourne shell,或sh,它是Version 7 Unix默认的Unix shell,替代执行文件同为sh的Thompson shell。微软的Windows操作系统也提供了命令行壳层的功能,它们是Windows 95 / 98下的command.com、Windows NT内核下的cmd.exe以及PowerShell

下面的Python 列表包含了Unix系统常见的shell:

shells = [
    'Bourne shell(sh)',
    'Almquist shell(ash)',
    'Debian Almquist shell(dash)',
    'Bourne-Again shell(bash)',
    'Korn shell(ksh)',
    'Z shell(zsh)',
    'C shell(csh)',
    'TENEX C shell(tcsh)',
    'EMACS shell (eshell)',
    'Es shell(es)',
    'esh (Unix) – Easy Shell',
    'friendly interactive shell(fish)',
    'rc shell(rc)– shell for Plan 9 from Bell Labs and Unix',
    'scsh(Scheme Shell)',
    'Stand-alone Shell(sash)',
    'BeanShell(bsh,bsh.Interpreter , bsh.Console)',
    'Rhino JavaScript壳层(org.mozilla.javascript.tools.shell.Main)'
]

 通过shell,我们可以让操作系统执行Python程序。而Python是解释型语言,源代码不是直接翻译成机器语言,而是先翻译成中间代码,再由解释器对中间代码进行解释运行。有两种执行Python程序的方式,下面的Python 字典包含了这两种方式的信息:

# -*- coding: UTF-8 -*-
run = {
    "repl": {
        "title": "交互式编程( Interactive )",
        "desc": [
            "打开终端,输入 python 回车",
            "进入 Python 交互式命令行",
            "输入 print('monkey king is coding!')"
        ]
    },
    "source": {
        "title": "Python 源代源文件( File )",
        "desc": [
            "使用你喜欢的编辑器拷贝本练习的代码, 保存为run.py",
            "打开终端,cd 到 run.py 保存的目录",
            "输入 python run.py"
        ]
    }
}

 交互式命令行通常也称REPL,表示Read-Eval-Print-Loop,顾名思义是:读取-评估-打印-循环的意思。当你在shell环境里输入python并回车,就进入了Python的REPL环境,程序总是:

  1. 等待用户输入 Python 代码
  2. 当收到回车信号后就读取(Read)用户输入的 Python 代码
  3. 解释读取到的 Python 代码(Eval)
  4. 打印Python 代码的解释结果(Print)
  5. 回到步骤1,循环(Loop)该过程

实际上,我们在之前的习题里已经见过这样的程序,经过重新认识后,现在可以再次编写一个这样的REPL程序,功能需求如下

  • 提示用户选择想要了解的Python 的两种运行方式
  • 用户选择后输出对应Python 运行方式的基本说明,如果用户输入错误则提示后让用户重新选择
  • 循环该过程直到用户输入q退出
  • 最后输出用户学习了几种运行方式
# -*- coding: UTF-8 -*-
if __name__ == '__main__':
    run = {
        "i": {
            "title": "交互式编程( Interactive )",
            "desc": [
                "打开终端,输入 python 回车",
                "进入 Python 交互式命令行",
                "输入 print('monkey king is coding!')"
            ]
        },
        "f": {
            "title": "Python 源代源文件( File )",
            "desc": [
                "使用你喜欢的编辑器拷贝本练习的代码, 保存为run.py",
                "打开终端,cd 到 run.py 保存的目录",
                "输入 python run.py"
            ]
        }
    }

    print("有两种基本的方式运行 Python")
    for s in run:
        item = run.get(s)
        print("* {}: {}".format(s, item['title']))

    has_learn_i = False
    has_learn_f = False

    # TODO(You): 请在此实现代码

    if has_learn_i and has_learn_f:
        print("[2/2]您已完成两种 Python 运行方式的学习")
    elif has_learn_f:
        print("[1/2]您已完成 Python 源代码方式运行学习")
    elif has_learn_i:
        print("[1/2]您已完成 Python 交互式命令行运行学习")
    else:
        print("[0/2]您似乎跳过了运行方式的学习?期待下次光临!")

 程序的示例操作过程如下:

有两种基本的方式运行 Python
* repl: 交互式编程( Interactive )
* source: Python 源代源文件( File )
请选择你想了解的 Python 运行方式(输入:r/s选择,输入 q 退出):r
0. 打开终端,输入 python 回车
1. 进入 Python 交互式命令行
2. 输入 print('monkey king is coding!')
请选择你想了解的 Python 运行方式(输入:r/s选择,输入 q 退出):s
0. 使用你喜欢的编辑器拷贝本练习的代码, 保存为run.py
1. 打开终端,cd 到 run.py 保存的目录
2. 输入 python run.py
请选择你想了解的 Python 运行方式(输入:r/s选择,输入 q 退出):q
[2/2]您已完成两种 Python 运行方式的学习

以下选项是对代码中TODO部分的多种实现,你能找出实现错误的选项吗?

while True:
    ret = input("请选择你想了解的 Python 运行方式(输入:r/s选择,输入 q 退出):")
    if ret == 'r' or ret == 's':
        has_learn_repl = ret=='r'
        has_learn_source = ret=='s'
        desc = run.get(shoutcut_keys.get(ret))['desc']
        for i in range(0, len(desc)):
            print("{}. {}".format(i, desc[i]))
    elif ret != 'q':
        print("[错误] 不支持的运行方式")
        break
    else:
        pass