bash shell 临时笔记
来源:互联网 发布:white trash 知乎 编辑:程序博客网 时间:2024/05/21 06:11
1. 1变量替换
1. 2参数替换
1.1.1 变量的名字是它的值保存的地方。引用它的值称为变量替换(variable substitution)。.
如 果variable1是一个变量的名字,那么$variable1就是引用这个变量的值
变量赋值: var_name="var_value" 等号两边不能有空格 ;给变量赋的值中有空白字符,“ ”引号是必须的
read var_name
for var_name in num1 num 2
var_name=$(cmd) 命令替换,注意要保持命令行输出的完整性,最好var_name="$(cmd)" ,使用双引号
变量替换: $var_name 等同于 ${var_name} 在某些场合使用$variable形式会引起错误,这时你可能需要使用${variable}的形式了
"$var_name" 在一个双引号(" ")里的变量引用不会禁止变量替换。所以双引号被称为部分引用,有时也称为"弱引用"
变量替换不能用‘$var_name’ 一个单引号里(' ')的变量替换是被禁止的,变量名只被解释为普通的字面意思
1.1.2 一个未初始化的变量有一个”null”值――表示从没有被赋值过(注意null值不等于零)。虽然有时在数学运算会被当成0 ,但是不可靠,但是该行为无法预期 。
1.1.3 变量没有类型。
本质上来说,Bash变量是字符串,但是根据环境的不同,Bash允许变量有整数计算和比较。其中的决定因素是变量的值是不是只含有数字
1.1.4特殊变量种类
局部变量 local loc_var=23 # 声明为局部变量
环境变量
1.1.4.1
每次一个Shell启动时,它都会创建新的合适的环境变量。如果它增加或是更新一个环境变量,都会使这个Shell的环境表得到更新(译者注:换句话说,更改或增加
的变量会立即生效),并且这个Shell所有的子进程(即它执行的命令)能继承它的环境变量。(译者注:准确地说,应该是后继生成的子进程才会继承Shell的新环
境量,已经运行的子进程并不会得到它的新环境变量)。
1.1.4.2
如果一个脚本要设置一个环境变量,则需要将它导出(”export”),也就是说要通知到脚本的环境表。这就是export命令的功能。这样子脚本才会看到这个新修改变量
一个脚本只能导出(export)变量到子进程,也就是说只能导出到由此脚本生成的命令或进程中。在一个命令行中运行的脚本不能导出一个变量影响到命令行的环境。
子进程不能导出变量到生成它的父进程中
位置参数
注意$0
shift ;
$* $@ ; $* 和$@ 结合不同的IFS,代表的东西可能不一样
2.1.1设置变量的属性 r x i
declare或typeset内建命令(它们是完全相同的)可以用来限定变量的属性.
declare [+/-][rxi][变量名称=设置值]或declare-f
参数说明:
+/- "-"可用来指定变量的属性,"+"则是取消变量所设的属性。
-f 仅显示函数。
r 将变量设置为只读。
x 指定的变量会成为环境变量,可供shell以外的程序来使用。
i [设置值]可以是数值,字符串或运算式。
使用内建的declare可以来限定变量的范围, foo (){ declare FOO="bar" } 局部变量
2.1.2 变量的间接引用
变量间接引用的实际用处是什么? 它提供了Bash具有C中一点指针的功能 .
Bash不支持指针运算,这极大地限制了间接引用的用处。事实上,在脚本语言里间接引用是一个蹩脚地东西
a=letter_of_alphabet # 变量"a"保存着另外一个变量的名字. letter_of_alphabet=z
# 间接引用. eval a=\$$a
2.1.3 间接引用用到的命令字 eval
eval的作用是再次执行命令行处理,也就是说,对一个命令行,执行两次命令行处理
2.1.3.1与eval一起记忆的一个命令let
let 命令是 BASH 中用于计算的工具,用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量。如果表达式中包含了空格或其他特殊字符,则必须引起来。
shell程序中的操作默认都是字符串操作,在要运行数学运算符的时候可能得到意想不到的答案,所以用let
2.1.3.2 与let一起的算术运算
let不允许只出现等号右边的计算,用“ ”或者表达式中间没有空格,不需要$。let ″j=i*6+2″等价于((j=i*6+2)),
let 和 expr 的运算是整数运算,不包括浮点预算
2.1.4 变量的检查和初始化赋值
${parameter-default}, ${parameter:-default}
前者变量没有被声明(变量的值是NULL,也看做被声明),就使用这个default作为默认值;
后者变量没有被设置(变量的值是NULL,也是没有被设置),就使用default默认值
${parameter=default}, ${parameter:=default} 等同于上面
${parameter?err_msg}, ${parameter:?err_msg} 变量没有被声明或者被设置,打印err信息
${parameter+alt_value},${parameter:+alt_value}
如果变量parameter被声明或被设置,使用alt_value作为新值,否则使用空字符串
2.1.5 对变量的值就行修改
注意: Pattern 可以使用正则表达式,但是Replacement不能使用正则表达式
${var#Pattern}, ${var##Pattern}
“删除”从$var前端 开始的最短 或 最长匹配$Pattern的字符串. 必须是从头第一个字母开始的匹配,否则替换不了
”删除“从$var后端 开始的最短 或 最长匹配$Pattern的字符串。 必须是结尾最后一个字母的匹配。 记忆方法:键盘上三个键的位置紧挨着:#$%
”替换“如果变量var的前缀匹配模式Pattern,则用Replacement代替匹配模式的字符串.
”替换“如果变量var的后缀匹配模式Pattern,则用Replacement代替匹配模式的字符串.
注意: 这些pos 不能使用正则表达式------------------------------------
变量var被展开成从位移pos个字符往后的值.pos为负值,则从字符后面的倒数pos位置提取字符
从变量var中展开成从位移pos的字符往后最长为len的字符串。
在变量var第一个匹配Pattern的字符串用Replacement代替. 变量中间的字符,不一定是开头或者结尾的字符
如果省略了Replacement ,则第一个匹配Pattern的字符串会被删除.
全局替换Global replacement.所有在变量var中被Pattern匹配到的都由Replacement代替.
匹配所有前面声明过的变量,并且变量名以varprefix开头.
如果name为一个数组变量,那么结果是该数组的所有下标的列表。如果name不是数组,那么,如果name为空,结果就为空,如果name不为空,结果就为0.2.1.7 变量的长度
字符串长度(即变量$var的字符个数)。
对于数组来说,${#array}是数组的第一个元素的长度.${#array[*]}和${#array[@]}表示数组中元素的个数
${#*}和${#@} 表示位置参数的个数
2.1.8 对变量操作的总结
# 表示求长度
!表示求变量的名字
# 表示开头匹配 ,扩展 /# /% ## %% //
% 表示结尾匹配
/ 表示求替换
没有/ 的都是删除操作
3.2.1.2( 命令1; 命令2; 命令3; ... )
{ command1; command2; command3; ... }
3.2.1.4 命令替换将会调用一个subshell :var=$() ; var=`do_action`
3.2.1.5 & ,提交后台作业
3.2.1.6 管道
3.2.1.7 . (source命令)或者file命令
3.2.1.8 exec命令
3.2.1.9 函数调用
3.2.2 受限shell
#bin/bash -r 或者 set -r shell运行在受限模式下
这是一种安全策略, 目的是为了限制脚本用户的权限 , 受限shell模式下如下操作不能执行:
使用cd 命令更改工作目录.
3.2.3 命令替换
将一个命令的输出赋值给某一个变量 。
var=`do_action` 允许嵌套的,但要用\转义``
var=$(do_action) 允许嵌套的
命令替换甚至允许将整个文件的内容放到变量中, 可以使用重定向或者cat命令。不要将2进制文件的内容保存到变量中
variable1=`<file1` # 将"file1"的内容放到"variable1"中.
variable2=`cat file2` # 将"file2"的内容放到"variable2"中. 但是这行将会fork一个新进程
3.2.4 进程替换
进程替换则是把一个进程的输出回馈给另一个进程 (换句话说,它把一个命令的结果发送给另一个命令).
>(command)
<(command) 在"<" 或or ">" 与圆括号之间是没有空格的. 如果加了空格将会引起错误信息
进程替换能比较两个不同命令之间的输出:$ comm <(ls -l) <(ls -al) ; diff <(ls $first_directory) <(ls $second_directory)
4.1 测试
4.1.1 测试结构
if any_thing
if test any_thing
if [ 空格分隔的变量 ]
[ 空格分割的变量 ] && || 不能用在这个内建命令中 , 与 或 -a -o
if [[ ]]
[[ ]] 与 或 && ||
(( )) 算术比较, 返回值和 [ ] 相反
4.1.2 文件类的比较
-e 文件存在
这个测试选项可以用于检查脚本中是否标准输入 ([ -t 0 ])或标准输出([ -t 1 ])是一个终端.
如果一个目录的sgid标志被设置,在这个目录下创建的文件都属于拥有此目录的用户组,而不必是创建文件的用户所属的组。这个特性对在一个工作组里的同
享目录很有用处。
一个root用户拥有的二进制执行文件如果设置了设置-用户-ID位(suid)标志普通用户可以以root权限运行。[1] 这对需要存取系统硬件的执行程序(比如说pppd
和cdrecord)很有用。如果没有设置suid位,则这些二进制执行程序不能由非root的普通用户调用。
4.1.3 算术比较
-eq 等于 if [ "$a" -eq "$b" ]
-ne 不等于 if [ "$a" -ne "$b" ]
-gt 大于 if [ "$a" -gt "$b" ]
-ge 大于等于 if [ "$a" -ge "$b" ]
-lt 小于 if [ "$a" -lt "$b" ]
-le 小于等于 if [ "$a" -le "$b" ]
< 小于(在双括号里使用) (("$a" < "$b"))
<= 小于等于 (在双括号里使用)(("$a" <= "$b"))
> 大于 (在双括号里使用) (("$a" > "$b"))
>= 大于等于(在双括号里使用)(("$a" >= "$b"))
4.1.4 字符串比较
< 小于,依照ASCII字符排列顺序
if [[ "$a" < "$b" ]] 符号
if [ "$a" \< "$b" ] 内建命令 所以 要转义
if [[ "$a" > "$b" ]]
if [ "$a" \> "$b" ]
4.2 流程控制
4.2.1 for
2种形式: for var in action or $var-list
for(( a=2; a<var;a++ )) c 风格 ,var没有$
4.2.2 while
2种形式: while [ ] or [[ ]] or action
while(( a < var )) c 风格,var没有$
4.2.3 util
util [ ] or [[ ]] or action until [[ condition ]] 是直到conditon 成立,才不执行do done操作
4.2.4 case
case "$var_name" in 对变量使用""并不是强制的,因为不会发生单词分离
“$case1”)
do_sth
;; case没有break,没有do done
"$case2")
do_sth
;; case 没有break,没有do done
esac
4.2.5 select
select var_name in $var_list
do
action
break;
done
4.2.6 if [ ] 或 [[ ]] 或 action 或 test
then
do_sth
else if [ ] [[ ]] test action 或者elif
then
do_sth
else
do_sth
fi
fi 注意, 有几个fi就要有几个fi ; 上面如果使用elif,那么下面只要一个fi就可以了 。
5.数组
数组是多个变量的存储,数组的变量时array[num], 等同于一般的变量var; 要访问一个数组元素,可以使用花括号来访问,即${array[xx]},0可以省略为${array}
数组元素没有类型,不同类型的元素可以放在同一个数组里
5.1 数组定义
declare -a array
array =() ()表明变量是数组
5.2 数组初始化
5.2.1 array[0]=$var 等同于变量赋值
5.2.2 array=($var0 $var1 $var2 .....)
5.2.3 array=([2]=$var [24]=$var)
5.3 增加一个元素到数组 不同于c,数组可以扩展
array=("$array[@]" "new1") 相当于,重新写了扁数组中的所有元素
array[${#array[@]}=new1
5.4 调用数组
5.4.1 ${array[@]} ${array[*]} 数组中的所有元素
${#array[@]} ${#array[*]}数组中元素个数
${array[num]} 数组中array[num]的值,
${array} 等同于 ${array[0]}
5.4.2 ${array:pos:len} 数组从下标pos开始len个元素 , 即array[pos] array[pos+1]..array[pos+len-1]
${array[@]:0} ${array[@]} $array[*] 显示数组的所有元素
5.4.3 对数据某元素的调用
${array[N]:pos:len} 即 array[N]中,位置pos开始len个长度的字符
5.4.4 删除数组的某个元素
unset array[N] 删除array[N],等同于array[4]=
unset array 等同于 unset array[@] 删除整个数组
5.5 复制数组
array_2=($array[@])
array_2=("$array[@]") 这个会保持数组中的分割符
5.6 判断索引是否在数组里
if [ "name" in array ] 不能用 if [ -z array[name] ]
6.1 函数
一个函数是一个子程序,用于实现一串操作的代码块(code block),
6.1.1 func_name()
{ 有更好的可移植性 , 符合c语言的格式
}
function func_name
{
}
6.1.2 传给脚本的命令行参数怎么办?在函数内部可以看到它们吗?
除非显示的传给函数参数,否则函数看不到传给脚本的参数,例如看不到$1 $2 $3
6.1.3 函数里变量 和 参数 的作用域
6.1.3.1 函数定义的变量默认是global的,其作用域从“函数"被调用时"执行变量定义的地方”开始,到shell结束或被显示删除处为止
函数定义的变量也可以被显示定义成local的,其作用域局限于函数内。
函数调用之前,所有在函数内声明且没有明确声明为local的变量都可在函数体外可见
6.1.3.2 函数的参数是local的
6.1.3.3 脚本中定义的变量是global的,其作用域从"被定义"的地方开始,到shell结束或被显示删除的地方为止
6.1.4 函数的返回值 $? return的返回值也是写到$?里
func xxx
a=$? 不能写成a=$(func xxx)
6.1.4.1 return 内建命令 ,返回的最大正整数是255
如果没有return ,将返回函数最后一个执行命令的退出状态
6.1.4.2 为了函数可以返回字符串或是数组,用一个可在函数外可见的变量
6.1.4.3 rerurn 返回的最大正整数是255 ,如何返回更大的数值
一种获取大整数的"返回值"的办法是简单地将要返回的值赋给一个全局变量
更优雅的做法是在函数用 echo 打印"返回值到标准输出",然后使用命令替换(command substitution)捕捉此值
6.1.5 函数的输入重定向
函数本质上是一个代码块(code block), 这意味着它的标准输入可以被重定向
Function () { ... } < file # 也试一下这个: Function () { { ... } < file }
7.1 内部变量
OFS=\r\n
8.1 常用命令
find
rev
md5sum
printf printf “ string %d %u %s ” $var1 $var2 $var3
head head filename -n N 打印头N行 ; head filename -n -N 打印头N行之后的所有行
tail tail filename -n M 打印结尾M行; tail filename -n +M 打印头M行之后的所有行
bc hex=`echo "obase=16;ibase=10; $n" | bc` 十进制转化为16进制 ; echo $1+$2 | bc 浮点数计算
tput 光标属性
tput cup row_num col_num 将光标移到 row行 col列位置
tput cols 查看当前串口tty的列宽col
date +%a +%A +%b +%B 显示当前的时间,不同的显示格式 。 man date
9.1 全局变量
$LOGNAME
- bash shell 临时笔记
- shell(bash)学习笔记
- Bash Shell笔记
- bash shell学习笔记
- bash shell 学习笔记
- bash shell笔记
- linux bash shell 笔记
- bash这个shell(笔记)
- bash shell 学习笔记
- [Bash Shell] Shell学习笔记
- [Bash Shell] Shell学习笔记
- Bash Shell学习笔记一
- Bash Shell学习笔记二
- Bash Shell学习笔记三
- Bash Shell学习笔记四
- Bash Shell学习笔记五
- Bash shell 学习笔记六
- linux笔记七( Bash Shell )
- 使用python中的matplotlib进行绘图分析数据
- 算法训练 区间k大数查询
- R语言一元线性回归
- 算法1:求逆序对数与显著逆序对数(归并排序)
- Python 多线程
- bash shell 临时笔记
- 树莓派用户管理
- 算法训练 动态数组使用
- IPython和IPython Notebook的安装和简单应用
- 主板(一)
- XML之DOM解析
- Android原生库和架构层通信的socket
- MongoDB安装及基本使用
- xml如何获取节点,标签,属性,文本