终端里面的程序是怎样跑起来的

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

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

时间: 2024-10-12 17:32:55

终端里面的程序是怎样跑起来的的相关文章

【转】使程序在Linux下后台运行 (关掉终端继续让程序运行的方法)

一.为什么要使程序在后台执行 我们计算的程序都是周期很长的,通常要几个小时甚至一个星期.我们用的环境是用putty远程连接到日本Linux服务器.所以使程序在后台跑有以下三个好处: 1:我们这边是否关机不影响日本那边的程序运行.(不会像以前那样,我们这网络一断开,或一关机,程序就断掉或找不到数据,跑了几天的程序只能重头再来,很是烦恼) 2:不影响计算效率 2:让程序在后台跑后,不会占据终端,我们可以用终端做别的事情. 二.怎么样使程序在后台执行 方法有很多,这里主要列举两种.假如我们有程序pso

mac 从终端打开应用程序

用mac好久了,但是好多技巧都不会,真是惭愧.我发现我就是很不善于发掘新的东西,也不爱用新的东西. 楼下实验室的一个师姐也买了一个mac pro,不过她是因为得了2万的奖学金.那师姐对命令行的操作不太清楚,经常会来问我.然后每次总会有些我解决不了的问题.有些问题我从没遇到过,只好百度.本来别人是以为我在用mac,以为我会,这时候就觉得汗流浃背de. ################## launchpad 图标不在 Dock 中 ################### 这个很简单,只是我开始一直

mac终端运行java程序

以前都在Windows环境下开发java,今天在mac上配置了java环境,结果测试运行hello world的时候竟然出错, sudo javac helloworld.java能通过,sudo java helloworld.class竟然报错 --> ClassNotFound ??? Google才发现 mac终端运行java程序需要带上完整包结构 首先回到包的根路径 包路径:/java/com/test/src/helloworld.class cd ./java sudo java

《程序是怎样跑起来的》第一章有感

在没有读<程序是怎样跑起来的>,这本书之前,我对于第一章所讲解CPU在脑子中只是知道它相当于是计算机的大脑,内部由数百万至数亿个晶体管构成.这本书在开始是就先对CPU的内部结构进行了解析,知道了CPU的内部是由寄存器,控制器,运算器和时钟四部分构成,各部分之间由电流信号相互联通.后来又向我们解释了内存,接着有告诉我们CPU是寄存器的集合体,而这一过程中最主要的就是了解寄存器是程序把其作为对象来描述的. 通过这一部分知识的学习,使我对CPU的内部结构又了初步的了解,虽然还是模糊的概念,但是积少成

《程序是怎样跑起来的》第一章读后感

读了<程序是怎样跑起来的>这本书的第一章之后,让我对CPU的理解更加深入.刚开始我只认为它是相当于计算机的大脑,原来它对于程序员来说不止如此,它还是CPU,寄存器,内存,内存地址,程序计数器,累计寄存器,标志寄存器和基址寄存器.它的内部是由寄存器,控制器,运算器和时钟四部分构成. 平常上课的时候我只是知道老师让我们往电脑上敲代码,敲完后运行成功,自己再加深理解,懂得如何运行成功的就行了.但是通过对这一章的学习,我懂得了程序是怎么运行,它的运行原理.CPU的处理很简单,但是程序还是要靠我们的编程

程序是怎样跑起来的第7章有感

读<程序是怎样跑起来的>第七章有感 本章主要讲的是程序是在环境下运行的内容,首先操作系统和硬件决定了程序的运行环境,机器语言的编码被称为本地代码,程序员用C语言等编写的程序,在编写的阶段仅仅是文本文件,文本文件在任何情况下都能显示和编辑,称之为源代码,通过对源代码进行编译,就可以得到本地代码.CPU负责解析并运行从源代码编译而来的本地代码. Windows的前身操作系统是20世纪80年代的MS-DOS操作系统的广泛使用的时代,在MS-DOS的时代,如果想使用当时大热的文字处理软件----Jus

对比《网络是怎样连接的》PDF+《程序是怎样跑起来的》PDF+《计算机是怎样跑起来的》PDF

理解知识最好的办法是写一写汇编.从中感觉自己对浮点数在寄存器的存放机制了解还不够.加深了对基址寄存器和变址寄存器的了解.不足的地方在于有些例子陈旧了.记住0.1循环100相加不是10. 从计算机的内部结构开始讲起,以图配文的形式详细讲解了二进制.内存.数据压缩.源文件和可执行文件.操作系统和应用程序的关系.汇编语言.硬件控制方法等内容,目的是了解从用户双击程序图标到程序开始运行之间到底发生了什么.<程序是怎样跑起来的>图文并茂,通俗易懂,非常适合计算机爱好者阅读. <计算机是怎样跑起来的

ARM-LINUX学习笔记-(虚拟机linux串口终端以及USB程序下载,基于TQ2440)

昨天安装了ssh服务之后今天在windows上用xshell登陆发现登录不上,原因是使用了virtualbox的NAT模式,在NAT模式下,客户机可以很方便地上网,但是想要链接宿主机就需要打开网络地址映射 首先要知道ssh服务使用的是22端口,然后打开windows主机上的适配器,virtualbox安装了一张虚拟网卡,如下 虚拟地址为192.168.56.1,接下来在虚拟机的设置界面设置网络地址映射,首先还要知道虚拟机的IP地址,如下 地址为10.0.2.15,就可以去做端口转发了,位置如下

_ZNote_编程语言_Objective-C_用终端编译OC程序

某些情况下,仅仅想写一些简单的代码,可以不用Xcode,仅仅使用终端即可编译OC程序. 打开终端. 输入vi test.m 输入一下代码: #import <Foundation/Foundation.h> int main (int argc, char *argv[]) {     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];          NSLog(@"HelloWorld" ) ;