coreutils8.32 dirname命令和源码分析

本文介绍了一个名为dirname的命令,该命令用于获取文件的相对路径。核心功能由dir_len函数实现,该函数定义在dirname-lpgl.c中。文章详细展示了dirname命令的源代码,包括其如何处理命令行选项、如何输出结果等。

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

命令功能:获取文件的相对路径

核心函数:dir_len获取操作数前缀,定义在dirname-lpgl.c

#include <config.h>
#include <getopt.h>
#include <stdio.h>
#include <sys/types.h>

#include "system.h"
#include "error.h"

/* 程序名 */
#define PROGRAM_NAME "dirname"
/* 作者 */
#define AUTHORS \
  proper_name ("David MacKenzie"), \
  proper_name ("Jim Meyering")
/* 处理长选项 */
static struct option const longopts[] =
{
  {"zero", no_argument, NULL, 'z'},
  {GETOPT_HELP_OPTION_DECL},
  {GETOPT_VERSION_OPTION_DECL},
  {NULL, 0, NULL, 0}
};

void
usage (int status)
{
  if (status != EXIT_SUCCESS)
    emit_try_help ();
  else
    {
      printf (_("\
Usage: %s [OPTION] NAME...\n\
"),
              program_name);
      fputs (_("\
Output each NAME with its last non-slash component and trailing slashes\n\
removed; if NAME contains no /'s, output '.' (meaning the current directory).\n\
\n\
"), stdout);
      fputs (_("\
  -z, --zero     end each output line with NUL, not newline\n\
"), stdout);
      fputs (HELP_OPTION_DESCRIPTION, stdout);
      fputs (VERSION_OPTION_DESCRIPTION, stdout);
      printf (_("\
\n\
Examples:\n\
  %s /usr/bin/          -> \"/usr\"\n\
  %s dir1/str dir2/str  -> \"dir1\" followed by \"dir2\"\n\
  %s stdio.h            -> \".\"\n\
"),
              program_name, program_name, program_name);
      emit_ancillary_info (PROGRAM_NAME);
    }
  exit (status);
}

int
main (int argc, char **argv)
{
  static char const dot = '.';
  bool use_nuls = false;
  char const *result;
  size_t len;

  initialize_main (&argc, &argv);
  set_program_name (argv[0]);
  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);

  atexit (close_stdout);

  while (true)
    {
      int c = getopt_long (argc, argv, "z", longopts, NULL);

      if (c == -1)
        break;

      switch (c)
        {
        case 'z': /* 用NULL分隔输出 不是用换行符了 */
          use_nuls = true;
          break;

        case_GETOPT_HELP_CHAR;
        case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);

        default:
          usage (EXIT_FAILURE);
        }
    }

  /* 缺少操作数 */
  if (argc < optind + 1)
    {
      error (0, 0, _("missing operand"));
      usage (EXIT_FAILURE);
    }

  /* 遍历操作数 */
  for (; optind < argc; optind++)
    {
      result = argv[optind]; /* 保存操作数,从第一个开始 */
      len = dir_len (result); /* 保存操作数长度(文件前缀长度) */

      /* 如果操作数len为空,那么就将输出路径设为.和len设为1 */
      if (! len)
        {
          result = &dot;
          len = 1;
        }

      fwrite (result, 1, len, stdout); /* 输出处理后的操作数 */
      putchar (use_nuls ? '\0' :'\n'); /* 处理选项:-z 判断是否开启了该选项来做出对应处理,开启了就每个操作数的分隔用\0,默认换行 */
    }

  return EXIT_SUCCESS;
}

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值