SHELL(bash)脚本编程七:源码简析

本文简要分析了Bash shell的源码,重点介绍了数据结构如单词、重定向和命令,以及命令执行的主要流程,包括解析和执行两个步骤。在解析阶段,bash读取命令并构建相应的数据结构,而在执行阶段,bash根据命令类型调用不同的执行函数,处理输入重定向,进行命令搜索与执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文对bash的源码(版本:4.2.46(1)-release)进行简要分析。

数据结构

bash是用C语言写成的,其源码中只使用了少量的数据结构:数组单向链表双向链表哈希表。几乎所有的bash结构都是用这些基本结构实现的。

源码中最主要的结构都定义在根目录下头文件command.h中。

单词

bash在不同阶段传输信息并处理数据单元的数据结构是WORD_DESC

typedef struct word_desc {
  char *word;       /* Zero terminated string. */
  int flags;        /* Flags associated with this word. */
} WORD_DESC;

WORD_DESC表示一个单词,字符指针word指向一个以\0结尾的字符串,整型成员flags定义了该单词的类型。
当前源码中定义了二十多种单词类型,如W_HASDOLLAR表示该单词包含扩展字符$W_ASSIGNMENT表示该单词是一个赋值语句,W_GLOBEXP表示该单词是路径扩展(通配符扩展)之后的结果等等。

单词被组合为简单的链表WORD_LIST

typedef struct word_list {
  struct word_list *next;
  WORD_DESC *word;
} WORD_LIST;

WORD_LIST在shell中无处不在。一个简单的命令就是一个单词列表,展开结果同样是一个单词列表,内置命令的参数还是一个单词列表。

重定向

结构REDIRECT描述了一条命令的重定向链表,包含指向下一个REDIRECT对象的next指针:

typedef struct redirect {
  struct redirect *next;    /* Next element, or NULL. */
  REDIRECTEE redirector;    /* Descriptor or varname to be redirected. */
  int rflags;           /* Private flags for this redirection */
  int flags;            /* Flag value for `open'. */
  enum r_instruction  instruction; /* What to do with the information. */
  REDIRECTEE redirectee;    /* File descriptor or filename */
  char *here_doc_eof;       /* The word that appeared in <<foo. */
} REDIRECT;

整型成员flags定义了目标文件打开方式。
重定向描述符redirector的类型是一个联合体REDIRECTEE

typedef union {
  int dest;         /* Place to redirect REDIRECTOR to, or ... */
  WORD_DESC *filename;      /* filename to redirect to. */
} REDIRECTEE;

instruction是枚举型变量r_instruction,它定义了一个重定向的类型:

enum r_instruction {
  r_output_direction, r_input_direction, r_inputa_direction,
  r_appending_to, r_reading_until, r_reading_string,
  r_duplicating_input, r_duplicating_output, r_deblank_reading_until,
  r_close_this, r_err_and_out, r_input_output, r_output_force,
  r_duplicating_input_word, r_duplicating_output_word,
  r_move_input, r_move_output, r_move_input_word, r_move_output_word,
  r_append_err_and_out
};

REDIRECTEE中,如果重定向类型是ri_duplicating_input或者ri_duplicating_output则使用整型成员dest(如果其值为负则表示错误的重定向),否则使用结构指针成员filename
REDIRECT结构中的字符指针成员here_doc_eof,指定了重定向类型为Here Document(见这里)。

命令

命令COMMAND结构描述一条bash命令,对于复合命令,其内部可能还包含有其他命令:

typedef struct command {
  enum command_type type;   /* FOR CASE WHILE IF CONNECTION or SIMPLE. */
  int flags;            /* Flags controlling execution environment. */
  int line;         /* line number the command starts on */
  REDIRECT *redirects;      /* Special redirects for FOR CASE, etc. */
  union {
    struct for_com *For;
    struct case_com *Case;
    struct while_com *While;
    struct if_com *If;
    struct connection *Connection;
    struct simple_com *Simple;
    struct function_def *Function_def;
    struct group_com *Group;
#if defined (SELECT_COMMAND)
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值