01-在PATH中查找程序

需求分析

使用环境变量(例如MAILER和PAGER)的shell脚本都有一个隐藏的危险:有些设置指向的程序可能并不存在。如果你以前没有碰到过这种环境变量,那么应该将MAILER设置成你喜欢的电子邮件程序(例如/usr/bin/mailx),将PAGER设置成可以分屏浏览长文档的程序。假如你为了实现灵活性,打算使用PAGER设置代替系统默认的分页程序(通常是more或less程序)来显示脚本输出,你该怎样确保环境变量PAGER的值是一个有效的程序?

第一个脚本解决的问题正是如何测试能否在用户的环境变量PATH中找到指定的程序。该脚本也很好地演示了包括脚本函数和变量切分(variable slicing)在内的各种shell脚本编写技术。代码清单1-1显示了如何验证路径是否有效。

代码实现
#!/bin/bash
# inpath -- 验证指定程序是否有效,或者能否在PATH目录列表中找到in_path(){# 尝试在环境变量PATH中找到给定的命令。如果找到,返回0;如果没有找到,返回1。# 注意:该函数会临时修改IFS(内部字段分隔符),不过在函数执行完毕时会将其恢复原状。cmd=$1	ourpath=$2result=1oldIFS=$IFSIFS=":"for directory in $ourpathdoif [ -x $directory/$cmd ];then# 如果执行到此处,那么表明我们已经找到了该命令。result=0fidoneIFS=$oldIFSreturn $result
}checkForCmdInPath() {var=$1if [ "$var" != "" ];thenif [ "${var:0:1}" = "/" ]; thenif [ ! -x $var ];thenreturn 1fielif ! in_path $var "$PATH"; then	return 2fifi
}
  • [ "${var:0:1}" = "/" ]这个语法只是用来查看指定路径是否以斜线起始。只要确定传入脚本的路径包含起始斜线,就检查是否能在文件系统中找到该路径。
  • 如果路径开头是/,则假定给出的是绝对路径,然后使用bash操作符-x [ ! -x $var ]检查其是否存在。
  • 否则,将该值交给函数inpathelif ! in_path $var "$PATH",看看能否在默认的环境变量PATH的各个目录中找到。
工作原理

checkForCmdInPath能够正常工作的关键在于,区分只包含程序名的变量(例如echo)与包含程序完整路径和文件名的变量(例如/bin/echo)。它的做法是检查给定值的第一个字符是否为/。因此,我们需要把第一个字符与变量值的其余部分分离开。

注意if [ "${var:0:1}" = "/" ]处的变量切分语法${var:0:1}是一种可以在字符串中指定子串的简写法,从偏移处开始,按照给定长度截取(如果没有提供长度,则返回余下的全部字符串)。例如,表达式${var:10}将会从第11个字符开始返回变量$var余下的值,而${var:10:5}则返回第11个到第15个字符。

运行脚本

要想以独立程序的形式运行这个脚本,首先需要在脚本底部加上一小段代码。这段代码负责获取用户输入并将其传给相应的函数。

if [ $# -ne 1 ];thenecho "Usage:$0 command" >&2exit 1
ficheckForCmdInPath "$1"
case $? in0) echo "$1 found in PATH"				;;1) echo "$1 not found or not found or not executable"	;;2) echo "$1 not found in PATH"				;;
esacexit 0
  • 添加上面的代码之后,就可以直接调用脚本了,如接下来的“运行结果”所示。使用脚本完成工作之后,记得要把这段代码删除或注释掉,不然随后将其作为库函数使用时就乱套了。

在测试该脚本的时候,我们使用3个程序名来调用inpath:一个存在的程序、一个虽然存在但没有列入PATH中的程序,以及一个不存在但包含完整的合格文件名和路径的程序。

sh inpath.sh echo 						# -> echo found in PATH
sh inpath.sh MrEcho 					# -> MrEcho not found in PATH
sh inpath.sh /usr/bin/MrEcho	# ->/usr/bin/MrEcho not found or not found or not executable
  • 脚本中最后添加的那段代码将函数in_path的结果转换成了更易于阅读的文字,所以现在我们可以很容易地看到每种情况都按照预期得以处理。
精益求精

如果你想在第一个脚本中就化身为代码忍者,可以将表达式${var:0:1}换成更为复杂的${var%${var#?}},后者是POSIX的变量切分写法。从外表上来看,这种写法嵌套了两个字符串切分。内部的${var#?}会提取变量var中除第一个字符之外的其余所有内容,其中#表示删除指定模式的第一处匹配,?是正则表达式,只匹配单个字符。

接下来,${var%pattern}会产生一个子串,其值为将指定模式从变量var中删除后所剩下的部分。在这个例子中,被删除的模式正是内部字符串切分的结果,所以最后剩下的就是整个字符串的第一个字符。

如果POSIX写法看起来太吓人,大多数shell(包括bash、ksh和zsh)也支持我们在该脚本中采用的${varname:start:size}这种形式。

当然,如果这两种方法你都不喜欢,还可以调用$(echo $var | cut -c1)。在bash编程中,解决问题的手段不止一种,可以通过不同的方式从系统中提取、转换或载入数据。重要的是要意识到并理解“殊途同归”并不意味着不同的方法之间存在优劣之分。

如果你想创建一种能够区分自己是独立运行还是被其他函数所调用的脚本,可以考虑在脚本开始部分加上一个条件测试:if [ "$BASH_SOURCE" = "$0" ]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/647866.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【赠书第19期】跨平台机器学习:ML.NET架构及应用编程

文章目录 前言 1 ML.NET架构 1.1 简介 1.2 架构特点 2 应用编程 2.1 数据处理 2.2 模型训练 2.3 模型评估 3 优势与展望 3.1 优势 3.2 展望 4 推荐图书 5 粉丝福利 前言 随着大数据时代的来临,机器学习技术在各个领域的应用越来越广泛。为了满足不同平…

解决linux下wps缺失字体的问题

1.安装Windows字体 这是最简单的解决方案。使用者可以通过以下方式安装Windows字体: 从Windows系统中得到所需字体文件。将字体文件复制到Linux系统中。一般在“/usr/share/fonts/truetype”目录下。 接着,在终端中输入命令sudo fc-cache就可以更新字…

龙年快乐,大烟花

烟花秀&#xff1a; 源码&#xff1a; <!DOCTYPE html> <html lang"en" > <head><meta charset"UTF-8"><title>2024新年快乐&#xff01;万事如意&#xff01;</title><meta name"viewport" content&q…

二、mongoose的使用,实现用户集合的操作

前言 mongodb&#xff1a;为了在node应用中与MongoDB交互&#xff0c;开发者需要使用MongoDB的驱动程序&#xff0c;所以安装的mongodb就是其驱动程序&#xff1b; mongoose: 是一个用于 MongoDB 的对象建模工具&#xff0c;提供了一个丰富的查询语言和许多其他功能&#xff0c…

Javadoc的讲解使用

概述&#xff1a;JavaDoc 是用于生成 Java 代码文档的工具。通过编写 JavaDoc 注释&#xff0c;可以为代码中的类、接口、方法、字段等元素添加文档注释&#xff0c;这些注释将被 JavaDoc 工具解析并生成相应的 HTML 文档。 目录 讲解 使用 结果 讲解 下面是一些关于 Java…

Linux内核--文件系统(四)虚拟文件系统详解

目录 一、引言 二、虚拟文件系统 ------>2.1、VFS 定义 ------>2.2、VFS 的对象 ------>2.3、超级块 super ------>2.4、索引节点 inode ------>2.5、目录项 dentry ------>2.6、文件 file ------>2.7、文件共享 ------>2.8、打开文件流程 …

VScode通过SSH连接远程服务器

一. 在VScode上安装SSH插件 直接在VScode应用商店搜索安装即可: 二. 登陆服务器的root用户 使用命令"su -"或者"sudo -i -u root"都可以。 三.用vim编辑器打开服务器的SSH配置文件,把PasswordAuthentication后面的no改为yes&#xff0c;表示SSH允许远程密…

day21 事件流、事件捕获、事件冒泡、阻止冒泡、解绑事件

目录 事件流总结&#xff1a; 事件捕获示例&#xff1a; 事件冒泡阻止冒泡&#xff08;阻断事件流动传播&#xff0c;不止在冒泡阶段有效&#xff0c;捕获阶段也有效&#xff09;解绑事件鼠标经过事件的区别&#xff1a; 事件流 事件流指的是事件完整执行过程中的流动路径。 事…

数据采集与预处理01: 项目1 数据采集与预处理准备

数据采集与预处理01&#xff1a; 项目1 数据采集与预处理准备 任务1 认识数据采集技术&#xff0c;熟悉数据采集平台 数据采集&#xff1a;足够的数据量是企业大数据战略建设的基础&#xff0c;因此数据采集成为大数据分析的前站。数据采集是大数据价值挖掘中重要的一环&#…

WordPress你好多莉插件(Hello Dolly)有什么用?如何修改展示内容?

每次我们成功搭建好WordPress网站后&#xff0c;都可以在后台 >> 插件 >> 已安装的插件&#xff0c;在插件列表中可以看到有一个“你好多莉”的插件&#xff08;英文插件Hello Dolly&#xff09;。具体如下图所示&#xff1a; 那么这个你好多莉插件到底有什么用呢&…

基于springboot+vue的古典舞在线交流平台

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目背景…

Scala基础知识

scala 1、scala简介 ​ scala是运行在JVM上的多范式编程语言&#xff0c;同时支持面向对象和面向函数式编程。 2、scala解释器 要启动scala解释器&#xff0c;只需要以下几步&#xff1a; 按住windows键 r输入scala即可 在scala命令提示窗口中执行:quit&#xff0c;即可退…

直播核心岗位基础内容

一.直播间核心岗位 1.直播间前端岗位 前端岗位分工 &#xff08;1&#xff09;主播岗位职责 &#xff08;2&#xff09;场控岗位职责 &#xff08;3&#xff09;助理岗位职责 中端岗位分工 &#xff08;1&#xff09;运营岗位职责 &#xff08;2&#xff09;中控岗位职责 …

Centos7安装python3.7.13以及pip23.3.2

拿到机器发现只有自带的python2.X&#xff0c;但是算法cplex求解器需要用到Python3.7&#xff0c;安装过程遇到一些问题&#xff0c;记录下来&#xff1a; 如果需要卸载python3 1、卸载python3 rpm -qa|grep python3|xargs rpm -ev --allmatches --nodeps 2、 删除所有残余…

三维柔性焊接平台怎样来安装支架的(河北北重)

安装支架是安装三维柔性焊接平台的重要部分&#xff0c;它提供平台稳定的支撑结构。下面是安装支架的一般步骤&#xff1a; 确定支架的位置&#xff1a;根据焊接平台的尺寸和工作区域的要求&#xff0c;确定支架的安装位置。 准备安装材料&#xff1a;根据支架的设计和要求&am…

整数反转算法(leetcode第7题)

题目描述&#xff1a; 给你一个 32 位的有符号整数 x &#xff0c;返回将 x 中的数字部分反转后的结果。如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] &#xff0c;就返回 0。假设环境不允许存储 64 位整数&#xff08;有符号或无符号&#xff09;。示例 1…

如何用GPT快速写论文?

详情点击链接&#xff1a;如何用GPT快速写论文&#xff1f; 第一&#xff1a;2024年AI领域最新技术 1.OpenAI新模型-GPT-5 2.谷歌新模型-Gemini Ultra 3.Meta新模型-LLama3 4.科大讯飞-星火认知 5.百度-文心一言 6.MoonshotAI-Kimi 7.智谱AI-GLM-4 第二&#xff1a;Op…

kafka生产者与消费者

文章目录 一、 pom.xml依赖包二、yml配置文件三、消费者四、生产者总结 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 一、 pom.xml依赖包 <dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka<…

Java实战:轻松掌握文件重命名与路径提取技巧

目录 一、使用File类进行文件重命名应用场景1&#xff1a;文件上传到服务器后保持原有文件名 二、从字符串中提取文件路径应用场景2&#xff1a;只获取不带http前缀的文件路径url应用场景3&#xff1a;获取文件路径url下的其他文件 三、解决反斜杠字符的问题应用场景4&#xff…

如何提高图片分辨率?3个方法让图片秒变清晰

如何提高图片分辨率&#xff1f;在日常生活中&#xff0c;我们经常需要处理各种图片。有时候&#xff0c;这些图片的分辨率可能比较低&#xff0c;导致无法满足我们的需求。例如&#xff0c;当我们想将图片放大或裁剪时&#xff0c;低分辨率的图片可能会出现模糊、失真等问题。…