ls命令的实现和原理 [linux演习]

引子:

个人工作两年了, 一直从未总结自己所学, 本文章一是希望可以总结自己所学. 如果可以对各位有所帮助, 也算是文有所用了.
这是linux演习系列的第一篇. 主要是总结自己对linux的认识. 首先从shell开始..

命令及原理: ls

        在GUN代码中, ls命令和dir,vdir两个命令均属于同一份代码实现.  三个命令由变量ls_mode变量控制. 在ls的文件开头有基于ls_mode的宏定义, 可以看到不同的取值
        对应不同的命令.
  #define PROGRAM_NAME (ls_mode == LS_LS ? "ls" \
                        : (ls_mode == LS_MULTI_COL \
                           ? "dir" : "vdir"))
        ls命令运行时的颜色控制, 主要依赖与LS_COLORS环境变量. 
ls源码的入口调用了parse_ls_color函数. 该函数的主要功能为"解析LS_COLORS环境变量", 供ls的输出做颜色控制.
  if ((p = getenv ("LS_COLORS")) == NULL || *p == '\0')
    return;
值得说明的是, 即使LS_COLORS变量有值并不等于 ls命令输出时一定有颜色,  该变量只是进行颜色的配置, 而不是颜色的使用.
LS_COLORS变量主要指定文件类型以及对应的颜色值, 打印其值便可一窥究竟.
[nobody@myseo ~]$ echo $LS_COLORS
no=00:fi=00:di=00;34:ln=00;36:pi=40;33:so=00;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=00;32:*.cmd=00;32:*.exe=00;32:*.com=00;32:*.btm=00;32:*.bat=00;32:*.sh=00;32:*.csh=00;32:*.tar=00;31:*.tgz=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.zip=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.bz=00;31:*.tz=00;31:*.rpm=00;31:*.cpio=00;31:*.jpg=00;35:*.gif=00;35:*.bmp=00;35:*.xbm=00;35:*.xpm=00;35:*.png=00;35:*.tif=00;35:
何时输出颜色, 由ls命令自行判断, 判断依据有两个:    --color的取值, 以及输出句柄是否是终端(isatty函数判断输出句柄是否为tty, 当ls的输出被重定向时, 该函数返回false).
        case COLOR_OPTION:
          {
            int i;
            if (optarg)
              i = XARGMATCH ("--color", optarg, color_args, color_types);
            else
              /* Using --color with no argument is equivalent to using
                 --color=always.  */
              i = color_always;

            print_with_color = (i == color_always
                                || (i == color_if_tty
                                    && isatty (STDOUT_FILENO)));

            if (print_with_color)
              {
                /* Don't use TAB characters in output.  Some terminal
                   emulators can't handle the combination of tabs and
                   color codes on the same line.  */
                tabsize = 0;
              }
            break;
          }
这也就是为何ls命令非常智能, 在任何环境下都非常友好的输出.  PS:  苦恼于自定义shell颜色输出的码农们可以借鉴于此.
--color参数的取值范围可以从代码中看到, 常用的为tty, none, auto; 仔细研究代码还可以发现, 部分参数值如force等, 主要是为了兼容性而保留的.
static char const *const color_args[] =
{
  /* force and none are for compatibility with another color-ls version */
  "always", "yes", "force",
  "never", "no", "none",
  "auto", "tty", "if-tty", NULL
};
ls命令获取目录下项目信息的方式非常简单, 利用的是标准C接口, 函数opendir. 函数返回dirent结构体, 其中包含了非常丰富的文件元数据. 包括文件名, 大小, 权限, 所属等等.
代码段摘要重要部分, 给出如下, 粗略浏览即可知道其中的主要思路.
  DIR *dirp;
  struct dirent *next;

  errno = 0;
  dirp = opendir (name);
  if (format == long_format || print_block_size) {
      p = human_readable (total_blocks, buf, human_output_opts,
                          ST_NBLOCKSIZE, output_block_size);
      DIRED_FPUTS (p, stdout, strlen (p));
      DIRED_PUTCHAR ('\n');
  }
  if (cwd_n_used)
    print_current_files ();
关于LS命令, 先总结在这里.  
下一篇 ldd






你可能感兴趣的:(Linux演习,shell,linux)