shell 脚本关键字&符号
shell概念
"shell"既是一种解释型编程语言,也是一个这种编程语言的解释器的名字shell是解释型语言,就是解释器会一条一条的翻译每一条语句并执行,对比之下,C语言是编译型语言,编译器把整个工程编译成可执行文件才能执行在没有续行符(\回车)的情况下,shell脚本的一条语句以"回车"为结束任何一个shell脚本程序都必须在开头用#!标识使用的shell程序,如果用的是bash,那就是#!/bin/shshell脚本一行中的#之后的部分为注释刚刚写完的一个shell script程序通常是没有执行权限的,需要手动**$chmod +x filename.sh**来添加可执行权限shell语言本身并不包含linux内置的命令,那些命令本质上都是一个可以在shell环境中执行的程序,只是在shell环境中执行shell脚本可以调用这些程序而已。
特殊符号
$
表示取结果。和变量名一起使用表示取变量的值,和()一起使用表示取命令群组的执行结果
$tunset=123
$echo "$tunset"
123
$echo $(ls Downloads)
lukas-h.github.io-theme.zip youdao-dict_1.1.0-0-deepin_amd64.deb
( )
表示在"nested sub-shell"中划分一个命令群组(command group),如果我们希望里面的命令对之前和之后的设定不影响的话,就要用(),反之,如果需要在当前shell(non-named command group)中执行相关命令,就要用{}表示命令群组。在数学计算中就是数学中的()定义数组
$cat shell.sh
;./shell.sh
line
="123 25 36532 454"
(
line
="wwww"
echo "$line"
)
echo "$line"
wwww
123 25 36532 454
$arr=(0 1 2 var
)
$echo "${arr[0]}"
0
{ }
用作范围限定标明在"non-named command shell"中执行的命令群组。shell函数就是使用{}的特性来定义的配合:,-,+,=,#,/,%,?对变量进行操作
$echo $var
123
$echo $variable
$echo ${var}iable
123iable
$cat shell.sh
;./shell.sh
line
="123 25 36532 454"
{
line
="wwww"
echo "$line"
}
echo "$line"
wwww
wwww
$file=/opt/ros/jade/include/image_view/ImageViewConfig.h
$echo $
{file
opt/ros/jade/include/image_view/ImageViewConfig.h
$echo $
{file
ros/jade/include/image_view/ImageViewConfig.h
$echo $
{file
ImageViewConfig.h
$echo ${file%/*}
/opt/ros/jade/include/image_view
$echo ${file%%/i*}
/opt/ros/jade
$echo ${file:0:4}
/opt
$echo ${file:4:9}
/ros/jade
$echo ${file/opt/root}
/root/ros/jade/include/image_view/ImageViewConfig.h
$echo ${file//i/++}
/opt/ros/jade/++nclude/++mage_v++ew/ImageV++ewConf++g.h
$echo ${file-fault}
/opt/ros/jade/include/image_view/ImageViewConfig.h
$echo ${file1-fault}
fault
$echo ${file:-fault}
/opt/ros/jade/include/image_view/ImageViewConfig.h
$echo ${file+fault}
fault
$echo ${file:+fault}
fault
$echo ${file=fault}
/opt/ros/jade/include/image_view/ImageViewConfig.h
$echo ${file1}
$echo ${file1=fault}
fault
$echo ${file1}
fault
$echo ${file:=fault}
/opt/ros/jade/include/image_view/ImageViewConfig.h
$echo ${file?fault}
/opt/ros/jade/include/image_view/ImageViewConfig.h
$echo ${file:?fault}
$echo ${file}
/opt/ros/jade/include/image_view/ImageViewConfig.h
$echo ${#file}
50
(( ))
用作计算,shell支持十进制/十六进制/二进制的+ - * / % & += -= *= /= %= ++ – 等算术运算,以及| ^ ! > >= < <= !=等逻辑运算。同样的效果也可以使用expr ...来实现,但是expr是Linux的内置软件,并不是shell语言的关键字
$echo $((1 + 2))
3
$echo $((0xf + 1))
16
$cal=132
$echo $(($cal+1))
133
[ ]
用作取数组元素,使用${arr[n]}访问数组编号为n的元素
$arr=(0 1 2 var
)
$echo "${arr[0]}"
0
$echo "${arr[3]}"
var
两个反单引号表示命令替换,和$()是等价的。个人觉得看着比$()清晰,但是如果多层嵌套的话可能需要转义,此时就没有$()看着易懂。在下面的嵌套结构中,我们本意是先执行cmd3,将执行结果传给cmd2,再将结果传给cmd1
cmd1
`cmd2 `cmd3``
但是其实被解析成了下面这个
cmd1
`cmd2`cmd3 ``
为了解决这个问题,我们需要使用转义字符,写成下面这个样子才能正确的传达我们的意思
cmd
`cmd2 \`cmd3\``
但如果我们使用$(),就可以让代码更清晰
$echo `echo`echo 12`
` #被分解成了 echo `echo` echo 12``
echo 12
$echo `echo \
`echo 12\``
12
$echo $(echo $(echo 12))
12
|
管道表示将前一个命令的返回结果用作后一个命令的参数,管道的前后必须都是命令,管道是管理Linux十分有用的工具 $grep “test” file1.txt | wc -l
> >>
> 以新建的方式重定向,如果文件不存在就创建文件并将内容写入,如果文件存在就把文件清空再写入内容 >>以追加的方式重定向,如果文件不存在就创建文件并将内容写入,如果文件存在就在原文件后面写入内容
<
我们通常的操作就是文件,其实已经使用的输入重定向
2>
标准输入,标准输出,标准错误其实是三个完全不同的文件,虽然我们看起来标准输出和标准错误都输入到显示屏中显示,但是不能用输出重定向将错误重定向到其他文件标准输入,标准输出,标准错误的文件描述符分别是0,1,2,这也是错误重定向2>的由来
&&
&&前的命令执行成功了就继续执行后面的命令
||
||前的命令执行失败了就去执行后面的命令
;
不论;前的命令执行成功与否都去执行后面的命令
关键字
readonly
相当于C中的const,readonly将变量设为只读模式,任何针对他们的赋值都是错误的
$readonly var
=123
$var=345
bash: var:
readonly variable
unset
删除变量
unset var_name 删除变量var_name
unset -v first middle last 删除其他变量
unset -f fcn 删除函数
$tunset=123
$echo $tunset
123
$unset tunset
$echo $tunset
$
shift
用来截去来自列表的位置参数,从左侧开始,一旦执行shift,$1的初始值就会永远消失,取而代之的是$2的旧值,依次类推,$#的值也会依次减1 shift也可以带一个参数,表示一次截取的个数
$cat shell.sh
echo "${1}"
shift
echo "${1}"
$./*.sh 123 456
123
456
set
设置新的位置参数
$set qq ww ee
$echo "${1}"
qq
$echo "${0}"
bash
$echo "${2}"
ww
$echo "$#"
3
export
添加变量到变量导出列表,即如果在shell中执行子shell,该变量将作为环境变量从而在子shell中变得可以使用。
$cat shell.sh
echo "$NEWENV"
$NEWENV=123
$./shell.sh
$export NEWENV
$./shell.sh
123
exit
提前结束标本
test
test 和[ ]既是一个linux缺省安装的软件命令,又是一个shell关键字。两者的功能都是一模一样的