从PATH说起的shell命令行替换

2024-06-23 20:58

本文主要是介绍从PATH说起的shell命令行替换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

许久之前,师弟问了我一个问题,为什么shell中添加环境变量的写法是下面这种方式

PATH=~/.lib:$PATH; export PATH

而下面这种会报错呢?

$PATH=~/.lib:$PATH; export PATH

当时我的回答是,"shell就是这样子规定的呀"。 回答的同时,也突然间发现有些自己感觉很熟悉的概念,原来自己并没有那么清楚,因此这一篇讲讲shell的命令行替换。先说结论

shell会在命令执行前对命令行进行一些替换

shell替换有如下几种:

替换语法含义
历史!之前使用命令
大括号{}指定的文本
代字号~username用户的主目录
变量$, ${...}shell和环境变量
算术$((..))整数运算
命令替换`...`, $(...)运行在子shell里命令的输出
路径名*,?,[...],[^...]文件系统中匹配的文件名

历史替换是以!开头的替换方式,以下面历史记录为例

2013053-292e0778400f0688.png
历史记录
$ !! # 执行上一个命令,即history
$ !1021 # 支持第1021个命令 即ls
$ !-2 # 执行倒数第二个命令,即ls

大括号替换: 它会将{...}里的内容展开为多个单词,可以快速创建有一定规律的文件. 下面这个命令就把"chap0{1..3}"替换成了chap01, chap02, chap03, 以及每个都还有一个html和text对应。

$ mkdir -p chap0{1..3}/{html,text}
$ tree chap0*
chap01
├── html
└── text
chap02
├── html
└── text
chap03
├── html
└── text

代字号代替: 我们经常会看到别人文章会写用vim ~/.bashrc修改家目录下的配置文件,其中~默认就会替代成自己家目录路径,可以用echo ~确认。

那么问题来了,如何我想快速到别人的家目录下,应该怎么操作。只要在~加上别人的用户名就行了。比如说我/home 下还有一个用户叫做abc, 那么查看它家目录下的内容就是

ls ~abc

注: ~a可以用tab补全成~abc

变量替换: shell会把${变量名}或者$变量名替换成变量所指代的具体字符,比如说我将abc指代为ls,那么shell就会将$abc解释成ls,然后执行ls

abc=ls
$abs
# Desktop  bin  biosoft  blastdb  miniconda3  ncbi

也就是$PATH=~/.lib:$PATH; export PATH报错的原因是,shell在执行命令前会把$PATH成原来PATH里的字符串,显然无法达到修改PATH的目的

算术替换: shell命令行支持整数型的数学运算,下面的运算都是可以的,但是就别拿100/2.5这种浮点运算为难shell了。

echo $((1+2))
echo $((1-2))
echo $((100*101))
echo $((100/50))

命令替换:这个替换非常的实用,可以将shell命令的输入结果立刻作为输入,而不是额外创建一个变量命。有一个应用场景就是在的分析报告里加上完成时间点

touch reports.$(date +%d%b%Y).log

路径名替换:路径替换的语法就4种,*表示0或更多的任意字符,?表示一个任意字符,[...]表示括号内的字符之一,[^...]不包括括号内的字符

以上就是shell命令行替换的几种形式。当然为了再一次强调"shell会在命令执行前对命令行进行一些替换",下面举一个反面例子来说明下。

Linux的/etc目录下有很多以conf结尾的配置文件,我们可以用find命令快速的定位到它们。

find /etc -name *.conf

上面的命令看起来没啥毛病,但是只要多做一件事情,就会有报错哦

touch a.conf b.conf
find /etc -name *.conf
# 如下是报错
find: paths must precede expression: b.conf
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec|time] [path...] [expression]

你会不会好奇,明明是相同的命令,却又不同的境遇呢?让我解释下,在刚开始的时候,文件下面没有"a.conf","b.conf",尽管shell看到"*"会有一种进行通配的冲动,但是很可惜没有对象让它统配。后来我们创建了这两个文件,给shell找到通配的机会,于是实际执行的命令就成了 "find /etc -name a.conf b.conf"。 由于后面这两个是文件路径,不符合find的命令要求,就导致了报错。

其实报错还好,有些时候没有报错,程序运行得到错误的结果反而更惨

如何避免这种错误呢?我们就需要用到"避免\*这个元字符被shell解释。

除了双引号,避免shell进行替换的符号还有 反斜杠\ , 和单引号 '. 单引号和双引号的区别在于,单引号内部所有字符都是普通字符而已,而双引号里的美元符号$, 感叹号! 和反引号 ` 还能被shell解释

这篇关于从PATH说起的shell命令行替换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1088261

相关文章

【Linux进阶】UNIX体系结构分解——操作系统,内核,shell

1.什么是操作系统? 从严格意义上说,可将操作系统定义为一种软件,它控制计算机硬件资源,提供程序运行环境。我们通常将这种软件称为内核(kerel),因为它相对较小,而且位于环境的核心。  从广义上说,操作系统包括了内核和一些其他软件,这些软件使得计算机能够发挥作用,并使计算机具有自己的特生。这里所说的其他软件包括系统实用程序(system utility)、应用程序、shell以及公用函数库等

关于命令行参数argv(《学习OpenCV》)

在《学习OpenCV》这本书中,很多示例代码都用到了命令行参数。作为新手,之前总是很困扰,不知道怎么用。偶然的机会终于略知一二了。 在Visual Studio中,我们可以自行设置命令行参数。 如在这个示例程序中,我们想把图像存入argv[1]。 方法如下: 依次点击,项目、属性、配置属性、调试、命令参数。出现下面的界面: 然后进行编辑,即输入图像路径。如:E:\Lena.jpg

剑指Offer—编程题4 ( 替换空格)

一、题目:替换空格 题目:请实现一个函数,把字符串中的每个空格替换成"%20"。例如输入“We are happy.”,则输出“We%20are%20happy.”。    在网络编程中,如果URL参数中含有特殊字符,如空格、'#'等,可能导致服务器端无法获得正确的参数值。我们需要将这些特殊符号转换成服务器可以识别的字符。转换的规则是在'%'后面跟上ASCII码的两位十六进制的表示。

hbase中shell命令

HBase scan命令详解 - 简书https://www.jianshu.com/p/0ccfd59d73f4 Hbase中多版本(version)数据获取办法_牛奋lch-CSDN博客_hbase 多版本前言:本文介绍2种获取列的多版本数据的方式:shell和spring data hadoop一、hbase shell中如何获取    1、在shell端创建一个Hbase表create

Containerd命令行工具nerdctl

Containerd 客户端工具 nerdctl 相比Containerd自带的ctr工具,nerdctl操作方式更接近之前的docker命令。nerdctl 是一个与 docker cli 风格兼容的 containerd 客户端工具,而且直接兼容docker compose的语法的。 仓库:https://github.com/containerd/nerdctl 1. 安装 二进制文

Shell语法全解

Shell基础语法全解 一、shell简介二、shell格式2.1 新建一个shell脚本文件2.2 执行脚本方式 三、变量3.1系统变量3.2自定义变量3.3 特殊变量3.3.1 `$n` 传入变量3.3.2 `$#` 输入参数个数3.3.3 `$*`、`$@` 输入参数内容3.3.4 `$?` 上一条命令执行结果 四、运算符 `$[]`、`$(())`五、条件判断5.1判断数值大小5.

Android常用命令行——gradlew,adb,adb shell

gradlew 下面全是针对 windows 操作系统的。如果是 Linux / Mac 请直接用 ./ 前缀。 gradlew clean //类似Clean Project gradlew -v //查看Gradle、Groovy、Ant、JVM等的版本gradlew build --info //编译并打印日志gradlew dependencies --info //查看详细的依

Android自定义系列——9.Path详细用法

rXxx方法 rXxx方法的坐标使用的是相对位置(基于当前点的位移),而之前方法的坐标是绝对位置(基于当前坐标系的坐标)。 Path path = new Path();path.moveTo(100,100);path.lineTo(100,200);canvas.drawPath(path,mDeafultPaint); 在这个例子中,先移动点到坐标(100,100)处,之后再连接

Android自定义系列——8.Path之贝塞尔曲线

贝塞尔曲线能干什么 贝塞尔曲线作用十分广泛,简单举几个的栗子: QQ小红点拖拽效果一些炫酷的下拉刷新控件阅读软件的翻书效果一些平滑的折线图的制作很多炫酷的动画效果 理解贝塞尔曲线的原理 一阶曲线原理: 一阶曲线是没有控制点的,仅有两个数据点(A 和 B),最终动态过程如下: (本文中贝塞尔曲线相关的动态演示图片来自维基百科)。一阶曲线其实就是前面讲解过的lineTo。 二阶曲线

Android自定义系列——7.Path之基本操作

Path常用方法表 为了兼容性(偷懒) 本表格中去除了部分API21(即安卓版本5.0)以上才添加的方法。 作用相关方法备注移动起点moveTo移动下一次操作的起点位置设置终点setLastPoint重置当前path中最后一个点位置,如果在绘制之前调用,效果和moveTo相同连接直线lineTo添加上一个点到当前点之间的直线到Path闭合路径close连接第一个点连接到最后一个点,形成一个闭合