shell语法

2024-02-19 19:06:56 浏览数 (2)

shell语法

一门新的语言

Linux中常见的脚本

sh:/usr/bin/sh或/bin/sh

bash:/bin/bash

csh:/usr/bin/csh

ksh:/usr/bin/ksh

zsh

开头必须使用 #! /bin/bash指名bash为脚本解释器

运行方式:

作为可执行文件:

chmod x test.sh使脚本具有可执行权限

./test.sh当前路径下执行(相对路径)

/home/acs/test.sh绝对路径下执行

~/test.sh家目录下执行

用解释器执行

bash test.sh

echo

意思和c 中cout 或 printf相同

注释

井号后面的都是注释,(与py相同)

其实脚本解释的时候#! /bin/bash解释的时候也是注释,只是系统识别为脚本解释器

多行注释:前 :<<EOF后:EOF;其中EOF也可以换成其他字符串,或者符号(必须首位相同)

变量

变量的定义

定义变量不需要¥符号

name1=’yxc’ (单引号定于字符串)

name2=”yxc” (双引号定义字符串)

name3=yxc (可以不加引号,同样表示字符串)

注意等号两边不能有空格!!!否则会报错

使用变量

使用变量需要加上¥(此符号在bash中意为取值),或者$(),花括号是可选的,主要是为了帮助解释器识别边界

echo $yxc

echo $(yxc)

echo会自动换行

错误:echo $namesacwing,因为没有括号,边界判断不对,不知道是namesacwing还是names

只读变量

readonly 变量(相当于c 中的const,声明了一个只读变量)

declare -r 变量

删除变量

unset(类似于c 终端undef),如果一个变量被删除,后面调用的时候会替换为空(NULL)

变量类型

自定义变量(局部变量):子进程不能访问的变量

环境变量(全局变量):子进程可以访问的变量

自定义变量转环境变量

export 变量名

declare -x 变量名

此时可以在子进程中使用变量

使用bash

使用bash会将原进程bash睡眠掉,进入一个新的bash子进程

退出:exit或者ctrl d

环境变量转自定义变量

declare x 变量名(可以理解为给变量赋予了自定义权限)

字符串

字符串可以使用单引号,也可以使用双引号,也可以不使用引号

单引号和双引号的区别(不加引号和双引号相同)

单引号中的内容会原样输出,不会执行,不会取变量(即不会转义),即没有使用&符号取值

双引号中的内容可以执行,可以取变量,即可以使用&取值

取出字符串的长度

¥后面加井号

echo ${井号name},即可以取出name的长度(注意这个地方是花括号)

提取子串

根据下标取值

echo ${name:m:n}注意这个每一个下标前都有冒号

查看自己开了多少进程

top可以查看

按下退出

文件参数变量

在执行shell脚本时可以想脚本传递参数,$1时第一个参数,$2是第二个参数…,特殊的是$0是文件名(包含路径)

$#:文件传入参数的个数(不包括文件名)

$*:由所有参数构成的用空格隔开的字符串,整体为字符串用双引号括起来

$@:每个参数分别用双引号括起来的字符串(@和*都是取所有的意思)

$$:脚本当前运行的进程ID

$?:上一条命令的退出状态(注意不是stdout,而是exit code),0表示正常退出,其他值表示错误

$(command):返回command这条命令的stdout(注意区分stdout和exit code,输出的数是stdout,例如cout,而退出状态是exit code,例如c 中的return)

command 返回command这条命令的stdout,(~上面的`)(7,8等价)

$()小括号是获取stdout的值,${}是取变量的值

数组

数组中可以存放多个不同的值,只支持一位数组,初始化时不需要指定数组大小(和py中的list一样不需要指定数组大小)

定义

数组用小括号表示,元素之间用空格隔开,如:array=(1 abc “def” yxc)

也可以直接定义数组中某个元素的值,如:array[0]=1,array[1]=abc,array[2]=”def”

读取数组中某个元素的值

格式:${array[index]}

echo ${array[0]}

读取整个数组

格式:(@和*都是取所有的意思)

$(array[@])

$(array[*])

expr命令

格式:expr 表达式 ####说明:

用空格隔开每一项

用反斜杠放在shell特定的字符前面,发现表达式运行错误时,可以试试转义

包含空格和其他特殊字符的字符串要用引号括起来

expr会在stdout中输出结果,如果结果为真,stdout为1,否则为0

expr也有exit code返回值,如果为真,exit code为0,否则为1

stdout 和 exit code 返回值为互反(真时相反,假时也相反)

字符串表达式(以下参数都是在expr后面的)

输出长度:length STRING:返回STRING的长度

index STRING CHARSET:CHARSET中任意单个字符在STRING中最前面的字符位置,下标从1开始。如果子啊STRING中完全不存在CHARSET中的字符,则返回0

substr STRING POSITION LENGTH 返回STRING字符串中从POSITON开始,长度最大为LENGTH的子串。如果POSITION或LENGTH为负数,0或非数值,则返回空字符串(下标从1开始)  

整数表达式

expr支持普通算数操作,算数表达式优先级低于字符串表达式,高于逻辑表达式

  • — 加减运算,两端参数会转化为整数,如果转化失败则会报错

* / % 乘除取余运算,两端参数会转化为整数(*在shell中有特殊含义,所以需要转义)

()可以表示优先级,但是需要用反斜杠转义

逻辑表达式

| 或(c 中是||,少一半):如果第一个值不是0,则会返回第一个值,第二个值不会计算,如果第一个参数非空并且非0,则会返回第一个参数的值

& 与 (c 中是&&,少一半):如果第一个值是0,则不会计算第二个值(短路特性),如果都非空并且非0,则会返回第一个值

== 与 = 是同义词,但是还是要按照c 来写逻辑等号==,复制=

< <= > >= != == = 比较两端的参数,如果为true则返回1,否则返回0,expr首先尝试将两端的参数转换为整数,并做算数比较,如果转换失败,则按字符集排序规则做字符比较(strcmp)

需要转义的:*、()、>、<=、|、&

echo expr a b加号和数字之间有空格

代码语言:javascript复制
                                                                                                                                                                                                                                                                                                                                                                                                                                                       ### read命令(cin或scanf)

用于从标准输入中读入单行数据,当读到文件结束符时,exit code为1,否则为0

-p 添加提示信息(类似于input(提示信息))

-t 后面跟秒数,定义输入字符的等待时间,超过等待时间后会自动忽略此命令

echo命令(相当于cout或printf)

输出格式:echo STRING

显示普通字符串:echo “Hello acterminal”,引号也可以省略

显示转义字符:echo “"Hello acterminal"“注意只能使用双引号,单引号不能够转义

也可以省略最外面表示字符串的双引号:echo "Hello acterminal"

显示变量:注意一定要用双引号,单引号不能够转义:name=yxc echo “My name is $name”

显示换行:直接n无法显示换行转义,开启转义需要-e:例如:echo -e “Hin”,即可输出转义

强行不换行:-e后c,c可以取消最后的回车(和py中的end = “”相同),因为echo和py中的print相同,最后会自动换行。

显示结果到echo “Hello world” > output.txt

原样输出字符串,不进行转义或取变量:用单引号引起来

显示命令的执行结果:用`引起来

printf语句(c 中是以,隔开每一项,而shell中是以space隔开每一项)

格式:printf format-string [arguments…]

printf “%dn” yxc

shell中printf不自带换行,所以需要自己加上n(此时无需-e进行转义)

文件逻辑运算符

|与&单与和单或是expr中的(必须在expr中使用)

而||与&&双与和双或是bash中自带的,可以直接在bash中使用

也带有短路特性

表达式中的exit code为0表示真,非0表示假

可以根据短路特性来做if表达式

test命令

test命令用于判断文件类型,以及对变量做比较

test命令用exit code来返回结果,而不是使用stdout,0表示真,非0表示假

test -e test.sh && echo “exist” || echo “Not exist”这种情况,如果前面test判断为0(真就会执行逻辑与(虽然是0,但是也是真,这种情况下可以不去看是0还是1,直接根据真假判断))

文件类型判断

-e文件是否存在(exist)

-f是否为文件(file)

-d是否为目录(directory)

文件权限判断

-r文件是否可读

-w文件是否可写

-x文件是否可执行

-s文件是否为非空文件,是则返回0(真),否则返回1(假)

整数间的比较

-eq a是否等于b(equal)(为什么不是-e,因为-e是转义,已经被使用过,-e也可以是exist中的是否存在)

-ne a是否不等于b(not equal)

-gt a是否大于b(great test)

-lt a是否小于b(less test)

-ge a是否大于等于b(great or equal)

-le a是否小于等于b (less or equal)

注意区分expr和test

expr是stdout,1表示真,0表示假(就和if一样,if内部是1即为真)

test是exit code,0表示真,非0表示假(就和return一样,return 0即为真,return 一个非0的值即为假)

字符串比较

-z判断STRING是否为空,如果为空则返回true

-n判断STRING是否为非空,如果为非空则返回true(-n也可以省略)

== 判断s1和s2是否相等

!=判断s1和s2是否不相等

>和<判断(需要用反斜杠转义),结果等于使用strcmp(逐个字符的ascii码进行比较)

多重条件判定

命令格式:test -r filename -a -x filename(由2,3条来链接两个test命令,第二个命令不需要test)

-a:&&,and

-o:||,or

!:例如test ! -x filename:当filename不可执行时,返回true

判断符号

【】和test用法几乎一样,更常用于if语句中

[]内的每一项都要用空格隔开

中括号内的变量,最好用双引号括起来(为了防止当变量中有空格时&取值出现错误(too many arguments))

中括号内的常熟,最好用单或双引号括起来

判断语句

if then语句,(类似与c 中的if-else语句)if后面跟的是命令,不是值

if expr 3 < 3和if 0相同,但是0不是命令,所以无法执行

需要写if后面跟着命令 if expr 3 < 3

if then elif then else fi

case $变量 in 值1)…;;值2)…;;*)…;; esac

0 人点赞