热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

解析Shell的命令行参数

如何解决《解析Shell的命令行参数》经验,为你挑选了1个好方法。

我有一个要为一个夏季项目编写的shell。例如,我正在尝试解析命令行,

如果我打电话

ls -l

我需要解析

-l

部分。

因此,我可以将其传递给用于的参数向量execv。我知道我正确解析了它,但是由于某种原因,找不到目录。我可能想念什么吗?下面是我的代码。



1> rici..:

尽管strtok标准库功能可能很有用,但您需要了解其接口的缺点,这基本上是对粗心的陷阱。

在此程序中,您似乎偶然发现了strtok界面的两个最常见问题。请man strtok与该答案一起仔细阅读,以免将来陷入这些问题。另外,请勿将其strtok用作良好界面设计的示例。而是将其用作避免情况的模型:

隐藏的全球状态

strtok对保留在静态变量中的字符串指针进行操作。每当您strtok使用第一个非NULL参数进行调用时,它都会首先将此静态变量的值重置为该字符串。在对的每次调用结束时strtok,它将其静态变量设置为下一次扫描应开始的地址,该地址恰好在刚找到的令牌之后。

整个程序中只有一个静态变量实例,因此您不能交错strtok扫描两个不同的字符串。更糟糕的是,您无法调用本身strtokstrtok字符串扫描内调用的函数,因为该函数内的调用将重置strtok状态。

这意味着strtok在程序中进行多次扫描时,您必须格外小心。在您的情况下,在命名错误的变量初始化之后env

token = strtok(env, ":");

strtok可以将输入命令分为几个名字不完整的变量argv

argv = strtok(buf_copy, " ");

因此,当您以后想要查找的下一个组件时env

token = strtok(NULL, ":");

strtok的状态不再指向env; 相反,它指向buf_copy(并根据您的特定输入,在此位置buf_copy将找不到更多令牌)。

修改输入参数

的第一个参数strtok是a char*,而不是a const char*

通常,如果库函数具有字符串参数,则const char*除非函数打算修改字符串,否则应将参数声明为。或者,换句话说,const char*声明是一个承诺,即不会尝试修改该参数,如果没有做出承诺,则可能是有充分理由的。

而且,的确,如果您阅读strtok的文档,您会看到它通过用NUL字符覆盖一些分隔符来显式修改其输入字符串。这具有将原始字符串永久划分为单独标记的作用。有时候很好,但是如果您以后想再次引用字符串的原始值,可能会给您带来很多麻烦。通常,您会发现自己在复制原始字符串以进行调用strtok。(这通常是程序设计不当的征兆,或者信号strtok并不是真正用于解析的正确工具。)

在此特定程序中,陷阱是getenv()不返回环境变量值的副本。它直接将指针返回到环境变量表中。尽管返回类型getenvchar*,这可能使您认为修改值是可以的,但C标准显然告诉您不要:

指向的字符串不得由程序修改

不幸的是,Linux的manpage中没有禁止使用此功能getenv,但是该手册确实指出getenv了指向环境表的指针。如果您确实修改了所返回的字符串getenv,则很有可能(尽管不能保证)getenv对相同环境变量的后续调用将检索修改后的值。

这就是您要做的事情:由于您放开strtok了返回的字符串getenv(PATH),因此后续调用getenv(PATH)将看到一个值在第一个冒号处被截断。


推荐阅读
  • VS Code 中 .vscode 文件夹配置详解
    本文介绍了 VS Code 中 .vscode 文件夹下的配置文件及其作用,包括常用的预定义变量和三个关键配置文件:launch.json、tasks.json 和 c_cpp_properties.json。 ... [详细]
  • 去控件化在线文档处理,推动高效信创办公环境
    探讨在线文档处理去控件化的趋势及其对构建高效信创办公生态的影响。 ... [详细]
  • 本文深入探讨了分布式文件系统的核心概念及其在现代数据存储解决方案中的应用,特别是针对大规模数据处理的需求。文章不仅介绍了多种流行的分布式文件系统和NoSQL数据库,还提供了选择合适系统的指导原则。 ... [详细]
  • 本文档提供了详细的MySQL安装步骤,包括解压安装文件、选择安装类型、配置MySQL服务以及设置管理员密码等关键环节,帮助用户顺利完成MySQL的安装。 ... [详细]
  • 本文详细探讨了 HAProxy 的基本概念及其与 LVS(Linux Virtual Server)的比较,特别是在内核空间与用户空间的工作差异。文章还深入介绍了 HAProxy 独有的数据结构——弹性二叉树,以及其在高并发场景下的表现。 ... [详细]
  • GitHub基础指南:项目代码的部署与管理
    GitHub是一个广泛使用的开源代码托管平台,支持版本控制与协作开发。本文将指导开发者如何在GitHub上高效地管理和分享项目代码,包括项目的创建、代码的上传与下载等基本操作。 ... [详细]
  • 当Ubuntu虚拟机的存储空间不足时,可以通过VMware轻松地为其添加新的硬盘。本文详细介绍了从关闭虚拟机、添加新硬盘到分区、格式化及挂载整个过程的操作步骤。 ... [详细]
  • 本文探讨了Python的csv模块在不同操作系统上生成文件时,默认使用DOS风格的行尾字符(即'')的问题,并提供了如何修改这一行为的方法。 ... [详细]
  • 本文介绍了如何将Linux系统中的YUM源更换为阿里云镜像源,包括网络连通性测试、原YUM源的移除、阿里云YUM源的配置以及缓存的更新等步骤。 ... [详细]
  • FTP作为一种传统的文件传输协议,广泛用于不同设备间的文件交换。然而,随着网络安全需求的提升及传输效率的要求,选择合适的FTP客户端变得尤为重要。本文将介绍如何利用WinSCP这款强大且安全的工具,实现两台电脑之间的文件高效传输。 ... [详细]
  • 本文探讨了 Boost 库中的 Program Options 组件,这是一个强大的工具,用于解析命令行参数和配置文件。文章介绍了如何正确设置和使用该组件,包括处理复杂选项和负数值的方法。 ... [详细]
  • 对于初次购买阿里云服务器的新手用户来说,如何高效地利用服务器资源并成功部署网站是一个重要的课题。本文将详细指导您完成从购买服务器到网站上线的六个关键步骤。 ... [详细]
  • GCC(GNU Compiler Collection)是GNU项目下的一款功能全面且高效的多平台编译工具,广泛应用于Linux操作系统中。本文将详细介绍GCC的特点及其基本使用方法。 ... [详细]
  • 本文探讨了如何使Shell和程序同时响应Ctrl-C信号的方法,即通过将两者置于同一进程组并将其设为终端的前台进程组。 ... [详细]
  • 如何更换Anaconda和pip的国内镜像源
    本文详细介绍了如何通过国内多个知名镜像站(如北京外国语大学、中国科学技术大学、阿里巴巴等)更换Anaconda和pip的源,以提高软件包的下载速度和安装效率。 ... [详细]
author-avatar
梦亦碎i
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有