1、关于$
$是个在shell中有多种使用方式的东东。不经常使用时,也是很容易忘记的一个特殊标识符,记录一下比较常用的几种用法:
- $# : 获得脚本传入参数的个数。
- $? : 获得上面函数或脚本执行之后的返回值(或者叫退出码)。(默认成功执行之后返回0)
- $$ : 获得当前所在脚本的进程ID号。(通常会被作为生成唯一标识的一种手段)
- $! : 获得最后一个后台进程PID。(通常这个可以用来结合后台任务& 来完成一定时间内运行任务的需求:cmd & (sleep 10; kill -9 $! 2>/dev/null))
- $() : 相当于``,也用作命令替换,即先执行括号中的命令,然后返回命令执行的结果。
- $*/$@ : 获取传入脚本的全部参数。但两者在加上引号之后的行为有些差别,后者会把传入参数以空格为分割拆分成多个,前者则还是作为一个整体看待。另外,这个差异也跟脚本的传入参数是否使用了引号有关,具体看一下例子。
-
#a.sh为测试脚本,内容如下 #!/bin/bash echo "The passed in parameters are : $@" echo 'Test $@ : ' for arg in $@ do echo "$arg" done echo 'Test $*: ' for arg in $* do echo "$arg" done echo 'Test "$@" : ' for arg in "$@" do echo "$arg" done echo 'Test "$*": ' for arg in "$*" do echo "$arg" done ## 下面是几种不同调用输出的结果 # use nothing ./a.sh a b c d e The passed in parameters are : a b c d e Test $@ : a b c d e Test $*: a b c d e Test "$@" : a b c d e Test "$*": a b c d e # use " " ./a.sh "a b c d e" The passed in parameters are : a b c d e Test $@ : a b c d e Test $*: a b c d e Test "$@" : a b c d e Test "$*": a b c d e # use ' ' ./a.sh 'a b c d e' The passed in parameters are : a b c d e Test $@ : a b c d e Test $*: a b c d e Test "$@" : a b c d e Test "$*": a b c d e
- 当然,这个种表示还有很多细微的差别不太常用,具体的可以参考这里:http://www.tsnc.edu.cn/default/tsnc_wgrj/doc/abs-3.9.1_cn/html/internalvariables.html#APPREF
-
- ${}: 变量替换
- ${#var}:输出var变量的字符串长度。
-
var=123456789;echo ${#var} 9
-
- ${var#string}/${var##string}/${var%string}/${var%%string}:字符串截取(string中支持Globbing风格的通配符*和?)
-
var1=abcd12345abc6789 pattern1=a*c # *(通配符)匹配a - c之间的任意字符. #从左到右非贪婪式匹配,即匹配到最短的一个就停止,将匹配到的串截掉。 echo '${var1#$pattern1} =' "${var1#$pattern1}" # Output : ${var1#$pattern1} = d12345abc6789 #从左到右贪婪式匹配,即匹配到最长一个才停止,将匹配到的串截掉。 echo '${var1##$pattern1} =' "${var1##$pattern1}" # Output : ${var1##$pattern1} = 6789 pattern2=b*9 # 匹配'b'到'9'之间的任意字符 #从右到左非贪婪式匹配,即匹配到最短的一个就停止,将匹配到的串截掉。 echo '${var1%$pattern2} =' "${var1%$pattern2}" # Output : ${var1%$pattern2} = abcd12345a #从右到左贪婪式匹配,即匹配到最长的一个才停止,将匹配到的串截掉。 echo '${var1%%$pattern2} =' "${var1%%$pattern2}" # Output : ${var1%%$pattern2} = a # 这关于#和%谁截掉左边,谁截掉右边的记法,最简单的就是看看键盘上他们在$符号的左右位置。
#使用这种方式实现的basename的功能 path_name=/home/bozo/ideas/thoughts.for.today t=${path_name##/*/} echo $t #Output: thoughts.for.today
-
-
${var:pos}/${var:pos:len}: 相当于Java中String的subString方法,也是bash中以index方式截取字符串的方法。但这种方式即使下标越界,也不会有任何错误输出。。。
-
var1=abcd12345abc6789 echo ${var1:0} # abcd12345abc6789 echo ${var1:1} # bcd12345abc6789 echo ${var1:0:1} # a
-
-
${var/Pattern/Replacement}: 使用Replacement来替换变量var中第一个匹配Pattern的字符串。
-
var1=abcd-1234-defg;t=${var1/abcd/m*m-};echo $t # Output : m*m--1234-defg # pattern中同样支持*通配符,但同样也是Globbing风格。 var1=abcd-1234-defg;t=${var1/a*d/m*m-};echo $t # Output : m*m-efg
-
- ${var//Pattern/Replacement}:同上,当时多了一个斜杠之后,标识不仅仅替换第一个匹配的字符串,而是全局替换。
-
${var/#Pattern/Replacement}/${var/%Pattern/Replacement}: 这里#和%表示Pattern只匹配字符串的开头或者结尾,功能有点类似于RE中的^和$。
-
v0=abc1234zip1234abc v1=${v0/#abc/ABCDEF} echo "v1 = $v1" # v1 = ABCDEF1234zip1234abc v2=${v0/%abc/ABCDEF} echo "v2 = $v2" # v2 = abc1234zip1234ABCDEF # 123 is neither the prefix nor suffix, so the String will not be replaced. v3=${v0/#123/000} echo "v3 = $v3" # v3 = abc1234zip1234abc v4=${v0/%123/000} echo "v4 = $v4" # v4 = abc1234zip1234abc
-
- ${array[@]}/${array[*]}: 获取数组的全部元素(${array[index]为获取数组中下标为index的那一个元素)。
-
my_array=(a b c d e) echo 'Test ${my_array[@]}' for my in ${my_array[@]} do echo $my done echo 'Test ${my_array[*]}' for my in ${my_array[*]} do echo $my done #The following is the output Test ${my_array[@]} a b c d e Test ${my_array[*]} a b c d e
-
- ${#var}:输出var变量的字符串长度。
- $ : 在正则表达式(RE)中作为行结束符。
2、关于Globbing
Bash本身并不会识别正则表达式,在脚本中,使用RE的是命令和工具。比如sed、awk等工具。Bash仅仅做的是文件名的扩展(当然还有上面提到的关于字符串的替换时使用的通配符),也就是所谓的Globbing。Globbing所使用的通配符最常用的有这3个:*/?/^。
这里面最容易和标准正则表达式产生混淆的就是前面两个通配符。
在RE中,*和?的通配作用主要是基于某个特定的字符的,而在Globbing中,他们的通配作用却可以代表任何字符。具体看个例子:
ls -l -rw-r--r-- 1 sky staff 3269 9 29 15:29 velocity.log -rw-r--r-- 1 sky staff 0 10 6 19:10 velocityab.log -rw-r--r-- 1 sky staff 0 10 6 19:10 velocityyy.log ##Globbing style ls -l *.log -rw-r--r-- 1 sky staff 3269 9 29 15:29 velocity.log -rw-r--r-- 1 sky staff 0 10 6 19:10 velocityab.log -rw-r--r-- 1 sky staff 0 10 6 19:10 velocityyy.log ##RE style, nothing output to the console ls -l|egrep "*.log" egrep: repetition-operator operand invalid ##RE style again ls -l|egrep "velocity*.log" -rw-r--r-- 1 sky staff 3269 9 29 15:29 velocity.log -rw-r--r-- 1 sky staff 0 10 6 19:10 velocityyy.log
从上面的例子可以看出来,RE中,*是不能作为一个独立的“通配单元”存在的,但是Globbing中没有问题,但是需要注意的是,Globbing中*是不会通配以.开头的隐藏文件的。?会有上面类似的解释规则。所以在Globbing中,velocity.???可以被解释为velocity.log,但同样也可以被解释为velocity.123等。
3、关于各种[](包括[[]])
- []用作条件测试:基本上等价于shell内建的test。最常见的就是if/while等后面的判断条件。
- []用作数组元素:直接看例子
-
my_array=(a b c d e); echo "The first element is : ${my_array[0]}" #The first element is : a
-
- []用作RE中的字符范围:匹配中括号中字符集中的某一个字符。常用的可以参考如下的这些形式:[xyz]/[c-n]/[B-Pa-m]/[a-z0-9]/[^b-d](这里的^标识取反了)
- [[]]用作表达式的条件测试:它和[]的最大区别就是,内部支持&&/||/>/<等符号,这也是使得它的结构相对于[]更加通用。
4、关于整数运算扩展操作符(())
该结构允许整数运算和赋值。是Bash(注意,原生shell并不支持该结构)中C语言结构风格的一个表达式。常用的可以参考如下几种用法:((a=12))/((a++))/((++a))/((a--))/((--a))/((t = a<123?0:1)),这里需要注意两点:
- 由于(())本身的C语言语法风格,(())内部在使用Bash变量时,是不需要$前缀标识它的引用形式的。
- 注意上面例子中的最后一个,可以看出它支持多数编程语言中的典型的三元表达式哦。
5、关于重定向
Linux下,重定向输出的基本符号大家一般比较熟悉了。>表示覆盖式重定向,>>表示追加式重定向。这里需要强调的是:0,1,2这三个特殊的数字,作为3个特殊的文件描述符,已经被默认分配给了,stdin,stdout,stderr这3个特殊的“文件”。下面列出几个常用的利用重定向完成的小功能tip:
- 清空文件内容: : >a.txt 清空a.txt文件的内容。(这里某些shell下,省略前面的冒号,直接使用 >a.txt也可以,但不是所有shell都支持这种语法,所以通用性不用加上冒号的版本)
- 重定向错误输出到特定的文件中:比如,command 2>a.txt,执行command命令,同时将产生的错误输出信息,从终端中冲定向到a.txt中。
- 将标准和错误输出全部输出到特定文件中:比较典型的用法就是不关心命令的任何输出,将所有输出信息都丢入垃圾桶:command >/dev/null 2>&1。这个表达式如果不理解含义,很容易记错,误用成下面这个样子:
- command 2>&1 >/dev/null 这个表达式只能保证将stdout丢掉,但是如果有错误产生,还是会输出到屏幕上。原因是:命令解释到command 2>&1是,表示将stderr输出到stdout上(就是屏幕上),后面执行到>/dev/null时,表示将stdout输出丢掉。但是,在这之前,stderr已经被重定向到了当时的stdout(就是屏幕),所以这时的错误信息并不会丢掉,还是会输出到屏幕。
- 如果你已经决定不关心任何命令的输出信息,又觉得上面的写法有点啰嗦,那可以试试这个写法: command &>/dev/null 这个写法会不管三七二十一,直接把所有输出信息全部重定向到/dev/null,这里完全省略了默认的文件描述符1和2.
相关推荐
1. **多语言支持**:MySQL Shell 支持SQL、JavaScript和Python三种编程语言,允许用户根据个人喜好或项目需求选择最适合的语言进行数据库操作。 2. **自动完成和提示**:在Shell中,用户可以享受到自动补全和语法...
1. **安装与运行**:解压"sqlite-shell-win32-x86-3080200.zip"到任意目录,然后找到sqlite3.exe,双击运行或在命令行中输入其路径启动。 2. **连接数据库**:在命令行中,输入`.open 数据库文件名`,例如`.open ...
在Shell脚本中,转义字符用于改变字符的特殊含义,使其按字面意义处理。常见的转义字符包括: - `\c`: 显示后不换行。 - `\f`: 在终端屏幕上显示新行。 - `\n`: 换行。 - `\r`: 回车。 - `\t`: 制表符。 #### 条件...
1. **命令行基础**:了解如何在终端中启动和使用shell,学习基本的文件和目录操作,如`cd`(改变目录)、`ls`(列出目录内容)、`touch`(创建新文件)、`mv`(移动或重命名文件)和`rm`(删除文件)等。 2. **管道...
mysql-shell-8.0.18-windows-x86-64bit.zip MySQL Shell is an advanced command-line client and code editor for MySQL. In addition to SQL, MySQL Shell also offers scripting capabilities for JavaScript ...
1. **多语言支持**:MySQL Shell支持JavaScript、Python和SQL三种语言,用户可以根据自己的偏好选择合适的接口进行数据库操作。这对于那些熟悉这些语言的开发人员来说,可以更高效地完成工作。 2. **SQL交互模式**...
1. **SQL交互**:用户可以直接在Shell环境中输入SQL语句进行数据库查询和管理操作。 2. **JavaScript和Python接口**:对于喜欢使用脚本语言的开发者,MySQL Shell提供了JavaScript和Python两种语言的API,可以编写脚...
SQLite是一款开源、轻型的数据库管理系统,它无需单独的服务器进程,可以直接在应用程序中使用。"sqlite-shell-win32-x86-3080403" 是SQLite的Windows 32位版本的命令行界面工具,适用于x86架构的系统。这个版本号...
ChromeDriver是用于自动化谷歌浏览器(Chrome)的一种工具,它遵循Selenium WebDriver协议。在Web测试自动化领域,ChromeDriver...这篇内容将详细介绍ChromeDriver如何获取浏览器中的cookie,并与谷歌浏览器配合工作。
以shell脚本的形式写一个统计1-100以内的奇偶数的和与个数。
1. 内嵌数据库一般是用sqlite进行轻量级管理的。网上可以下到sqlite-shell-win32-x86: sqlite3.exe 2. 为了方便命令行执行,将sqlite3.exe放到svn 项目的主目录下,和.svn目录同级下。 3. 执行 sqlite3 .svn/wc.db ...
### Shell Script 编程学习笔记 #### 一、Shell 脚本初窥 ##### 示例: ```bash #!/bin/sh # 第1行:指定脚本解释器(声明使用的shell名称),这里是用/bin/sh做解释器的。“#!”是一个约定的标记 cd ~ # 第2行:...
If语句和Case语句是Shell脚本中常用的控制结构,前者用于基于条件的分支选择,后者则更适用于基于模式匹配的多选一情况。根据具体需求选择合适的控制结构,可以提高脚本的可读性和效率。 ### 14. For与While/Until...
1,shell 是大小写敏感的,空格敏感的! a!=A a=1(正确)a = 1(错误) 2,清屏命令 clear ?3,declare -x variable 设置环境变量 与普通变量的区别在于可以在之后的其他脚本和程序中使用。 4,双引号(“”)存在...
本文将基于《LINUX与UNIX SHELL编程指南》这本书的读书笔记,深入探讨Linux与Unix Shell编程的核心知识点。 一、Shell概述 Shell是一个命令解释器,它接收用户输入的命令并执行。在Linux和Unix系统中,常见的Shell...
官方离线安装包,亲测可用。使用rpm -ivh [rpm完整包名] 进行安装
PS1 变量是 bash shell 的一个特殊变量,它用来控制 shell 的提示符。 export 命令 在解决方案中,我们使用了 export 命令来将 PS1 变量导出到当前 shell 环境中。export 命令用来将 shell 变量导出到当前 shell ...
Linux运维-3.Shell编程-11shell基础-105shell特殊符号1.avi
官方离线安装包,亲测可用。使用rpm -ivh [rpm完整包名] 进行安装