zoukankan      html  css  js  c++  java
  • bash 源码分析

     



     

    • 下载解压 bash-3.2

     

    • 编译bash
    export LFS=/my/soft/mylfs
    tar xvf $LFS/sources/bash-3.2.tar.gz -C $LFS/sources/
    cd $LFS/sources/bash-3.2/
    
    
    patch -Np1 -i ../bash-3.2-fixes-5.patch
    
    
    ./configure --prefix=$LFS/builds --without-bash-malloc
    make
    make install

     

    • 常用的调用堆栈

     

    在读取命令之前执行一些命令,如PS1的打印
    bash [C/C++ Application]    
    bash [9867] [cores: 0]    
    Thread #1 9867 [core: 0] (Suspended : Step)    
    execute_builtin_or_function() at execute_cmd.c:3,562 0x42bf86    
    execute_simple_command() at execute_cmd.c:3,019 0x42bf86    
    execute_command_internal() at execute_cmd.c:672 0x42952e    
    parse_and_execute() at evalstring.c:275 0x45dc63    
    execute_variable_command() at parse.y:2,159 0x41e157    
    parse_command() at eval.c:215 0x41b1c2    
    read_command() at eval.c:266 0x41b2a6    
    reader_loop() at eval.c:132 0x41b4e4    
    main() at shell.c:715 0x41ac53    
    gdb (7.2)

     

    执行用户输入命令的堆栈
    bash [C/C++ Application]    
    bash [2689] [cores: 0]    
    Thread #1 2689 [core: 0] (Suspended : Step)    
    cd_builtin() at cd.def:163 0x45a830    
    execute_builtin() at execute_cmd.c:3,153 0x4283d1    
    execute_builtin_or_function() at execute_cmd.c:3,539 0x42bf60    
    execute_simple_command() at execute_cmd.c:3,019 0x42bf60    
    execute_command_internal() at execute_cmd.c:672 0x42952e    
    execute_command() at execute_cmd.c:352 0x429ffe    
    reader_loop() at eval.c:147 0x41b412    
    main() at shell.c:715 0x41ac53    
    gdb (7.2)
    execute_builtin_or_function 方法有一个分支,分为执行内建命令和执行函数
    if (builtin)
    result = execute_builtin (builtin, words, flags, 0);
    else
    result = execute_function (var, words, flags, fds_to_close, 0, 0);
    
    
    
    如果是执行函数,如何找到执行的函数呢?
    func = find_function (words->word->word);
    
    
    /* Return the pointer to the function implementing builtin command NAME. */
    sh_builtin_func_t *
    find_shell_builtin (name)
    char *name;
    {
    current_builtin = builtin_address_internal (name, 0);
    return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL);
    }
    • 执行内置命令的方法如下:
    static int
    execute_builtin (builtin, words, flags, subshell)
         sh_builtin_func_t *builtin;
         WORD_LIST *words;
         int flags, subshell;
    {
      int old_e_flag, result, eval_unwind;
      int isbltinenv;
    
      old_e_flag = exit_immediately_on_error;
      /* The eval builtin calls parse_and_execute, which does not know about
         the setting of flags, and always calls the execution functions with
         flags that will exit the shell on an error if -e is set.  If the
         eval builtin is being called, and we're supposed to ignore the exit
         value of the command, we turn the -e flag off ourselves, then
         restore it when the command completes. */
      if (subshell == 0 && builtin == eval_builtin && (flags & CMD_IGNORE_RETURN))
        {
          begin_unwind_frame ("eval_builtin");
          unwind_protect_int (exit_immediately_on_error);
          exit_immediately_on_error = 0;
          eval_unwind = 1;
        }
      else
        eval_unwind = 0;
    
      /* The temporary environment for a builtin is supposed to apply to
         all commands executed by that builtin.  Currently, this is a
         problem only with the `unset', `source' and `eval' builtins. */
    
      isbltinenv = (builtin == source_builtin || builtin == eval_builtin || builtin == unset_builtin);
    
      if (isbltinenv)
        {
          if (subshell == 0)
        begin_unwind_frame ("builtin_env");
    
          if (temporary_env)
        {
          push_scope (VC_BLTNENV, temporary_env);
          if (subshell == 0)
            add_unwind_protect (pop_scope, (flags & CMD_COMMAND_BUILTIN) ? 0 : "1");
              temporary_env = (HASH_TABLE *)NULL;      
        }
        }
    
      /* `return' does a longjmp() back to a saved environment in execute_function.
         If a variable assignment list preceded the command, and the shell is
         running in POSIX mode, we need to merge that into the shell_variables
         table, since `return' is a POSIX special builtin. */
      if (posixly_correct && subshell == 0 && builtin == return_builtin && temporary_env)
        {
          begin_unwind_frame ("return_temp_env");
          add_unwind_protect (merge_temporary_env, (char *)NULL);
        }
    
    /*
    执行执行的语句,会调用不同的内置方法执行具体的命令,如cd命令会执行cd.def中的cd_builtin方法,内置方法的文件都在builtins目录下
    */
      result = ((*builtin) (words->next));
    
      /* This shouldn't happen, but in case `return' comes back instead of
         longjmp'ing, we need to unwind. */
      if (posixly_correct && subshell == 0 && builtin == return_builtin && temporary_env)
        discard_unwind_frame ("return_temp_env");
    
      if (subshell == 0 && isbltinenv)
        run_unwind_frame ("builtin_env");
    
      if (eval_unwind)
        {
          exit_immediately_on_error += old_e_flag;
          discard_unwind_frame ("eval_builtin");
        }
    
      return (result);
    }

     

  • 相关阅读:
    springmvc简介
    AOP的通知类型和注解配置
    word技巧之将目录放置文档的左侧
    【刷题-LeetCode】151 Reverse Words in a String
    【刷题-LeetCode】148 Sort List
    【刷题-LeetCode】150 Evaluate Reverse Polish Notation
    【刷题-LeetCode】147 Insertion Sort List
    【经验总结-博客园】博客园Silence主题模板使用
    【数学】立个flag
    python面试题
  • 原文地址:https://www.cnblogs.com/fyzjhh/p/5216022.html
Copyright © 2011-2022 走看看