链接
就是linux操作命令,运行.sh文件相当于执行linux命令。
.sh就是命令集文件。
vi xxx.sh
在当前终端启动一个进程去执行脚本
新建的文件是没有执行权限的
需要文件有执行权限(x),同样会启动一个子进程执行shell脚本
chmod u+x xxx.sh
不会启动子进程执行脚本,当前进程终端执行脚本
不会启动子进程执行脚本,当前进程终端执行脚本
3,4会影响当前终端进程
因为以上原因,使用不同方法操作$0,会得出两种结果。
没有vim,下载vim就行
shell命令如果有问题,会提示,但是不会退出脚本的执行。
&> /dev/null------表示不保留任何输出
true和false是shell中的命令。
执行true-----返回成功状态码0
执行false-----返回失败状态码1
不是
在 Shell 中,作为数字,任何值都是真;作为状态码,0 表示真,非 0 表示假。
定义:name=wu
等号两遍不能有空格
变量名=value #<==赋值时不加引号
变量名='value' #<==赋值时加单引号
变量名="value" #<==赋值时加双引号
主要是对字符串中变量和命令的操作不同
字符串如果有空格,必须使用引号
不适用引号和使用双引号-----会解析出变量的值
使用单引号-----不会解析变量值,原样输出
如果字符串中含有空格,那么对变量解析就需要加上引号
如上,如果变量不加引号,解析出来的变量含有空格,就变量了两个字符串。
字符串如果有空格,必须使用引号
不适用引号和使用双引号-----会执行命令,将命令的执行结果拼接字符串
使用单引号-----不会执行命令,原样输出
使用:${name}或者$name
只要在引号中或者没有引号的地方遇到$系统都解析为引用变量。如果$只是一个字符就用\转义。
输出:echo ${name}
当变量后面连接有其他字符的时候,必须给变量加上大括号{},例如:dbname变量的值加上_tname就要改成${dbname}_tname。
{}约定一个字整体
{}用来指定哪一部分字符串是一个变量。
$a
${a}
字母,数字,下划线组成;不能以数字开头。
let value=10+20
需要加上双引号或者单引号,只能一单一双,不能单单双双。
空格
content="I am wu."
1,用户自定义的变量自在本脚有用,除非export导出。
不影响
只要是在这个文件中定义的变量,无论是在哪定义的,都可以可以在文件中的任意地方使用。
使用命令替换的地方一定要使用完整格式---$()
1,path=$(pwd)
2,path='netstat -t'
变量直接或者变量和值之间加上一个非字母,数字,下划线的字符就行,复杂的用“”括起来
命令要懂得合并使用
在当前bash进程创建的变量作用域只在当前进程,bash父进程和bahs子进程访问不了彼此的变量。
bash执行文件,子进程无法访问存在于父进程中的变量。
就是让父进程创建的变量可以在子进程中被访问
详情链接
举例:
定义一个shell脚本coppeliasim:
#! /bin/sh
export Coppeliasim_HOME=/home/xxx/CoppeliaSim_Edu_V4_4_0_rev0_Ubuntu18_04
$Coppeliasim_HOME/coppeliaSim.sh $*
运行coppeliasim的时候,coppeliasim种的变量Coppeliasim_HOME就会拷贝到coppliaSim.sh脚本中去使用。
就是这个子进程不需要访问父进程的某个变量时,用unset取消导出。
unset会直接讲变量从内存销毁。
所以对于export和unset,我本人理解是:
export是在子进程中创建和这个变量一样的变量。
unset的时候也是直接销毁。
什么是环境变量
就是一个变量(PATH---必须大写),用来保存指定的路径字符串的变量.
PATH保存多个路径,以冒号:隔开。
命令搜索路径
就是我们执行一个命令时,linux的终端进程会根据配置的PATH路径一个一个路径去找到这个命令,然后执行这个我们输入的命令。
env命令
echo $USER
USER变量保存当前用户名
echo $UID
注意:是冒号分隔
在当前进程配置的PATH只在当前进程有效。
每一个命令都是一个sh文件,但是为什么不用跑到命令所在文件去执行这个呢,就是因为这些命令的路径都在PATH中记录着。
linux系统里有两个bash命令。
bin下的bash是其他系统里会有的,单数usr下的bash其他系统不一定有。所哟i编程shell文件时,使用到bash时,需要指定使用哪个bash来执行这个shell脚本文件。
1,(())是一个命令;
2,(())中使用的变量不需要$符号;
3,只能对整形运算;
4,(())只会完成运算,没有结果输出,如果需要输出或者参与其他计算,一定要$取值;
1,这个一个命令;
2,使用变量不需要$符号;
3,只能对整形运算;
4,$[]和(())都可以用于一般的算术运算;
5,$[ ]不是if中的 [ ];
因为$[]有计算结果输出,(())没有计算结果输出,而是直接(())中就完成了。
1,let和$[],(())一样的作用;
2,(())比let效率更好;
var=1
1,var=$var+1
2,let var=$var+1
分析以上1和2的区别:
1的结果:var=1+1
2的结果:var=2
1是字符串,知识会对字符串中的变量进行解析。解析的结果参与字符串拼接;
2是算术运算。
1,expr运算的运算符和数值之间必须要有空格,否则就是字符串;
2,乘法必须转义;
bc (-q)......quit
scale指定小数位数
通过管道,将表达式传输给bc计算器即可。
variable=$(echo "options; expression" | bc)
options是bc的参数选项,不是你可以定义变量
bc
注意:
1,print只能在bc 中使用;
2,bc中的表达式可以用()括起来,也可以不用。
0~255
then后可以有多个语句,语句之间换行就行。
这个语句只有一种判断条件
注意:
1,else后没有then
2,else 后没有判断语句,没有命令。
3,只能有一个if,一个else。
因为命令执行之后只有成功和失败两种。
if---else语句以命令执行状态码是否返回0作为是否进行的条件。返回0表示命令执行成功,执行条件。
then和else后可以嵌套if--then--fi和if--else--fi。
每一层嵌套都要用fi来结尾
表达式非空,返回推出状态码0,否则返回非0.
[ num1 比较符号 num2 ]
第一个方括号之后和第二个方括号之前必须留有空格,否则就会报错.
对于条件测试,bash shell只能处理整数
字符串判断
字符串判断,>,<需要进行转义。
-n,-z检查字符串是否为空
()---开启子进程运行命令
(())---复杂表达式
(())也可以用于其他地方
在0和整数之间取反
在表达式前面加上!就可以,但是!左右都要有空格,连在一起就变成字符串了。
双括号命令既可以在if语句中使用,也可以在脚本中的普通命令里用来赋值。
注意:
1,表达式一定要在(())中,不能:
正确:
报错:需要一元表达式
退出码返回为2,不执行比较成功语句
&&,||
case variable in
pattern1 | pattern2) commands1;;
pattern3) commands2;;
*) default commands;;
esac
注意:
1,双引号结尾
2,)分割参数和命令
exit (退出状态密码)
$()----命令替换
$[]----整数运算
${}----变量限定
(())-----整数运算
[[ ]]-----
在bash shell执行command之前,会先创建一个子shell,然后在其中执行命令。如果命令成功结束,则退出状态码(参见第11章)会被设为0,then部分的命令就会被执行。如果命令的退出状态码不为0,则不执行then部分的命令.
1,不是所有的shell都支持双方括号。
2,和其他测试命令的区别就是可以使用通配符。
1,整数比较不能使用数学比较符号
for var in list
do commands
done
注意:
1,list可以是一系列值,也可以是一个变量;
2,列表的每一个值以空格分开;
如果特殊情况需要使用其他分隔符,需要改变分隔符---看链接
3,使用转义\对特殊字符进行转义,或者使用引号包含特殊字符;
for命令会遍历/home/rich/test/*匹配的结果。
问题:
有两种方法可以解决这个问题。
·使用转义字符(反斜线)将单引号转义。
·使用双引号来定义含有单引号的值。
链接
while test command
do
other commands
done
until test commands
do
other commands
done
循环可嵌套
break,continue都可以指定跳出的循环层数
1,位置参数和传递的参数一 一对应;
2,位置参数直接访问,不需要再加$符号。
3,参数之间是以空格分隔的,所以shell会将字符串包含的空格视为两个参数的分隔符。要想在参数值中加入空格,必须使用引号(单引号或双引号均可)
4,如果脚本需要的命令行参数不止9个,则仍可以继续加入更多的参数,但是需要稍微修改一下位置变量名。在第9个位置变量之后,必须在变量名两侧加上花括号,比如${10}。
5,$n要输出进行转义
read (-p "提示语句")变量
就可以获取用户输入的值,把值付给变量。
可以输入多个变量的多个值,多出的值给最后一个变量
其实显示了,看不到
注意:read命令读取文件。每次调用read命令都会从指定文件中读取一行文本。
重定向的左边都是命令,右边是文件,或者需要输入的数据。
重定向的文件如果不存在,会自动创建。
>后面是一个文件,如果文件不存在就创建。
输入重定向是文件输出的数据成为命令操作的对象。
用来将数据输入到命令
任何字符都可以用来作为内联输入重定向的起止标记。
stdout和stderr
怎么将输出的数据输入一个文件,不输出到显示屏---输出重定向
怎么指定从哪地方获取输入数据---------------------------输入重定向
临时重定向到文件---- 命令 > file
临时重定向到标准输出-----命令 >&1
临时重定向到标准错误-----命令 >&2
临时重定向到标准输入-----命令 <&1
在重定向到文件描述符时,必须在文件描述符索引值之前加一个&。
输入临时重定向就是从屏幕获取输入
输出临时重定向是把输出的数据指定输出到标准输出(屏幕)
临时错误重定向同理。
永久重定向作用域整个脚本执行期间
exec 0
exec 1>file1
exec 2>file2
永久输入重定向:该命令会告诉shell,它应该从文件file中而不是键盘上获取输入。
永久输出重定向是指定输出的数据输出到指定文件。
永久错误重定向同理。
命令 > file 或者 命令 1> file------代表标准输出重定向
命令 2> file--------------代表标准错误重定向
命令 0< file 或者 命令 < file--------------代表标准输入重定向
在shell中,可以使用重定向符号“>”和“2>”来将标准输出和标准错误输出(stderr)分别重定向到文件或者/dev/null,其中2代表标准错误输出,而1代表标准输出:
- >&2 :将标准输出重定向到标准错误输出。
例如,如果要将stderr重定向到一个文件,可以使用下面的命令:
```bash
command 2> error.log
```
上面的命令中,“command”代表要执行的命令,“2>”表示将标准错误输出重定向到文件“error.log”。
如果要将stderr和stdout都重定向到同一个文件,可以使用“&>”:
```bash
command &> output.log
```
上面的命令中,“&>”表示将标准错误输出和标准输出一起重定向到文件“output.log”。
如果想忽略stderr,可以将其重定向到/dev/null:
```bash
command 2> /dev/null
```
上面的命令中,所有标准错误输出都将被丢弃,不会被记录到任何地方。
注意:
1,重定向一定是命令的结果重定向,也就是重定向一定是作用在命令上的。
因为每一句shell都是一个命令。
2,以上都是覆盖方式重定向--->,也可以追加--->>.
>------重定向到文件
>&-----重定向到标准输出或者标准错误
命令 2> file
这样,如果命令执行成功,就没有信息写入文件,如果有错误信息就有错误信息写入日志文件。
链接
ehco---输出后换行
printf---输出后不换行
用于生成提示的echo命令使用了-n选项。该选项不会在字符串末尾输出换行符,允许脚本用户紧跟其后输入数据
#!/bin/bash
function list_func(){
dir=$1
file_list=`ls $dir`
for file in $file_list
do
if [ -f $dir/$file ]; then
echo "$dir/$file is file"
else
echo "$dir/$file is not file"
fi
done
}
1,function关键字
内部调用
function add(){
a=$1
sum=$2
for ((i=0;i<$a;i=$i+1))
do
sum=$(($sum+$i))
done
echo "sum=$sum"
}
add 100 0
外部调用
#!/bin/bash
source ./file_func.sh
list_func ./
1,source 加入头文件,后面指定文件路径
2,函数的调用就直接调用函数名
3,函数中的变量需要参数则直接跟在调用的函数名后面
必须先source 再调用
read -p "Please input range:" num
sum=0
for ((i=0; $i < $num; i=$i+1))
do
((sum=$sum+$i))
done
echo $sum
有时需要把信息写入日志文件。
怎么写入:
链接
set -e
e----exit:有错误就退出
链接
1,如果引号使用不对称:
没有同步得到磁盘---------sync
如果字符串变量为空,这个变量将不能和其他字符串比较,否则比较结果就是失败。