zoukankan      html  css  js  c++  java
  • 终端里面的程序是怎样跑起来的

      比如mac环境下在某个路径下面跑celery的任务,celery -A msg_task worker 对于这一段语句的理解其实就是用后面的这些参数跑起来celery的可执行文件;那具体是怎样跑起来的呢,分为如下的四个步骤。

    一:mac的环境变量
      mac 一般使用bash作为默认shell,Mac系统的环境变量,加载顺序为:
      Ⅰ.(系统级别,系统启动就会加载)
        /etc/profile /etc/paths
      Ⅱ.(当前用户级的环境变量,因为~文件夹本身就是登录人的home目录,根据shell的不同,加载的配置文件可能不一样,比如如果用的是zsh的话,那这边的第一个文件就会是~/.zshrc;然后如果其中的~/.bash_profile文件存在,后面的文件就会忽略不读,如果不存在,才会读后面的文件)
        ~/.bash_profile ~/.bash_login ~/.profile
      Ⅲ.(bash shell打开的时候载入的)
        ~/.bashrc
      比如我的电脑上面看见/etc/path文件里面的内容是
        /usr/local/bin
        /usr/bin
        /bin
        /usr/sbin
        /sbin
      然后在~/.zprofile的内容是PATH="/Library/Frameworks/Python.framework/Versions/3.4/bin:${PATH}"
      最后在~/.zshrc的内容是export PATH=/usr/local/sbin:$HOME/bin:/usr/local/bin:$PATH
      所以最后我们在终端里面打印环境变量PATH,使用echo $PATH 得到的信息是/usr/local/sbin:/Users/sunmenghua/bin:/usr/local/bin:/Library/Frameworks/Python.framework/Versions/3.4/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin,这就对应上了

    二:找到可执行文件
      在/usr/local/bin【路径1】和/Library/Frameworks/Python.framework/Versions/3.4/bin【路径2】路径下面,我们都发现了celery
      然而执行celery -A msg_task worker的时候,发现,执行有报错,说【路径1】下面的celery是一个错误的编译器(bad interpreter),并且/usr/ocal/opt/python3/bin/python3.5不存在,所以在【路径2】找到对应的可执行文件

    三:分析可执行文件

      打开文件,能够定位到入口是在celery模块中__main__.py里面的面函数,看到的内容是: 

    1 import re
    2 import sys
    3 from celery.__main__ import main
    4 if __name__ == '__main__':
    5   sys.argv[0] = re.sub(r'(-script.pyw|.exe)?$', '', sys.argv[0]) # 正则匹配与替换
    6   sys.exit(main())    # 退出时运行从celery模块的__main__.py里面的main函数

      篇外话:发现了一个比较有用处的模块,就是sys模块。之前我写脚本的时候,都是使用的tornado.options模块。使用形式是:  

    1 from tornado.options import options, define # 引入模块
    2 define("action", default="userinc", help="update static module") # 定义传进来的参数
    3 if __name__ == "__main__":
    4 options.parse_command_line() # 分析命令行里面传进来的所有参数,默认是sys.argv,然后会丢掉第一个参数sys.argv[0],因为它是程序名
    5 action=options.action    然后调用形式就是 python3 test.py --action=test,经过追踪tornado的源码,知道这个模块其实是在sys.args进行了一层封装
    四:找到python3模块  
    通过import celery ,然后help(celery),  
    Ⅰ.找到模块的源码所在地方为/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/celery/;  

    Ⅱ.用sublime打开对应的文件夹,先找__main__.py,在根据导入模块找到celery/bin/celery.py里面的main函数
    Ⅲ.找到执行方法是在class CeleryCommand的execute_from_commandline;
    Ⅳ.继续向上追溯,执行方法在celery.bin.base里面的execute_from_commandline;
    Ⅴ.打印调试,真正读参数是在setup_app_from_command(argv)
    Ⅵ.打印调试,往下走到self.find_app(app);
    Ⅶ.调用的是from celery.app.utils import find_app方法传给他的两个参数,一个app是上面传下来的参数,另一个是symbol_by_name,这个参数是一个函数,搞得非常复杂,简直太复杂了,绕的一大圈。
    ###这里尝试描述一下:
    ##A.find_app(app, symbol_by_name=self.symbol_by_name)使用的是当前类里面的函数;
    ##B.from celery.utils import imports
    ##def symbol_by_name(self, name, imp=imports.import_from_cwd):
    ##return imports.symbol_by_name(name, imp=imp)
    ##C0.但是在celery/utils.py里面又有from celery.utils.imports import import_from_cwd,symbol_by_name
    ##D0.继续去celery/utils/imports.py里面又发现:from kombu.utils.imports import symbol_by_name
    ##E0.找kombu/utils/imports.py,确实是最后的导入是在这边,可是这里的逻辑是如果没有传导入函数的话,那就用importlib.import_module做导入函数,否则用调用的时候传的导入函数;好吧,那我们使用的时候,其实在步骤B里面有传入一个导入函数,那我们就继续追着B看一下,这个导入函数是哪里传入进来的;
    ##C1:跟C0一样
    ##D1:像B的这种形式,那是没有传参数的,所以,这边得到的这个函数也是importlib.import_module

    上面的追踪不继续描述了,言语难以表达。
    不过在追踪的过程中,还是有几点理解。
      1.函数不调用就不执行。
        写一个简化的调用。

    def t1():
     print('t1')
    
    def main(c=t1):
     c()
     print('main')
    
    if __name__ == '__main__':
        main()
    def t1():
     print('t1')
    
    def main(c=t1):
     print('main')
    
    if __name__ == '__main__':
        main()

     


        

        第一个的打印是t1和main,第二个的打印是main
      2.后面跟别人聊,本来我以为这样子的代码应该算是一种比较糟糕的代码;但是被告知,这种难以理解代码的产生是面向对象编程和产品迭代产生的;调用某个新的模块的时候,不需要知道他的内部实现原理,只需要他的参数和返回,然后如果想拓展他,就直接拓展接口就好了。

    但我还是不太理解,后面再想想吧。

  • 相关阅读:
    SpringMVC处理请求
    SpringMVC的启动
    数据结构
    Collections工具类
    位运算
    web应用
    spring Environment
    servlet及jsp之间的请求转发
    spring AOP
    Spring 事件
  • 原文地址:https://www.cnblogs.com/summery91/p/6209550.html
Copyright © 2011-2022 走看看