AcWing
  • 首页
  • 活动
  • 题库
  • 竞赛
  • 应用
  • 更多
    • 题解
    • 分享
    • 商店
    • 问答
    • 吐槽
  • App
  • 登录/注册

Linux 笔记 3 - shell 语法-上

作者: 作者的头像   溯光 ,  2023-03-18 18:09:34 ,  所有人可见 ,  阅读 42


1


shell 语法

基础知识

如何学习

多动手多练习
不懂的查手册: help +具体命令 就知道了这个命令该怎么用了

shell 脚本能干啥

将重复的操作(主要是针对文件)组织起来,方便复用
常见的有很多种, 默认使用的是 bash

bash 脚本 需要 在开头写一个 #! /bin/bash,指明bash为脚本解释器

如何运行一个 shell 脚本

首先完成 shell 脚本的内容,
再以可执行文件的方式运行(常用)
1. 直接执行的话,需要有可执行权限,查看文件的权限:ls -l test.sh
所以需要为我们的脚本增加可执行权限(r 读权限, w 写权限, x 可执行权限) chmod +x 脚本名.sh.
2. 执行文件:可以在当前路径下执行,可以在绝对路径执行,可以在家目录下执行
1.png

也可以用解释器执行
2.png

注释

单行注释: #后面的内容就是注释.
多行注释: (其中 EOF 可以换成自定义的字符串,保证头尾相同就可以)

:<<EOF
    第一行注释
    第二行注释
    第三行注释
EOF

注释.png

变量

shell 中的变量都是字符串,

定义一个变量

注意定义的时候,=两边不能有空格

name1=acwing
name2='acwing'
name3="acwing"

使用定义好的变量

可以使用$, 或者 ${}. {}是可选的,主要为了帮助解释器识别变量边界
变量.png

只读变量

用 readonly 或者 declare 可以将变量设为只读变量

readonly name
declare -r name  

05-end.png

删除一个变量的值

unset 可以删除变量的值
将某个变量的值删除后,这个变量的值就是一个空字符串
06-end.jpg

局部变量与全局变量

局部变量不能被子进程访问到,一般我们自己定义的变量都是局部变量
全局变量又称为环境变量,可以被子进程访问到
在命令行输入bash 可以进入一个子进程,同时这个父进程就休眠,在子进程输入 exit 就可以退出子进程,回到父进程

局部变量变为全局变量

export name  # 第一种方法
declare -x name  # 第二种方法

全局变量变为局部变量

export name=yxc  # 定义环境变量
declare +x name  # 改为自定义变量

07局部变量与全局变量.png

字符串

定义字符串

定义一个字符串 可以用单引号,也可以用双引号,也可以不用引号(上面定义变量时的图)

单引号与双引号的区别:
单引号中的内容会原样输出,不会执行,不会取变量;
双引号中的内容可以执行,可以取变量;
08-1字符串单双引号.png

取字符串长度

${#variable} 

取子串

${variable:0:5} #从0开始取长度为 5 的子串

08-2字符串.png

默认变量

shell 里面会有一些默认的变量

$0 就是 路径+文件名
执行脚本的时候可以向其传递参数
$1 传入的第一个参数
$2 传入的第二个参数
...
$100 传入的第100个参数

09-end.jpg

还要一些其他的默认变量

$#  传入的参数个数 

$*  由所有参数构成的用空格隔开的字符串,如上例中值为"$1 $2 $3 $4"
$@  每个参数分别用双引号括起来的字符串,如上例中值为"$1" "$2" "$3" "$4"
(一般没差别)

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

$?  上一条命令的退出状态(exit code). 0表示正常退出,其他值表示错误

$(command)  返回command这条命令的stdout(可嵌套)
`command`   返回command这条命令的stdout(不可嵌套)

这里要注意 退出状态(exit code) 与标准输出(stdout) 的区别:
exit code 可以看做那个 main 函数的返回值(我们写main函数时,最后一句return 0. 这个 0 就是 exitcode)
stdout 可以看做是我们写的函数中的 cout 输入的内容
09-5.png

$(ls) 就返回了 ls 这条命令的stdout,也就是返回了当前目录下的所有文件

数组

定义数组时不需要指明大小
下标从 0 开始
只支持一维数组
数组中可以存放多个不同类型的值

定义数组

用小括号,数组元素之间的分隔符号是 空格<space>

array =(1 acwing "linux" "shell")
还可以直接定义某个位置的元素的值
array[0]=1
array[1000]=2

读取数组中的元素

${array[index]}

读取整个数组

${array[@]}
${array[*]}

数组的长度

这个数组的长度是实际的数组中的元素个数

${#array[@]}
${#array[*]}

09-array-end.png

expr 命令

expr 命令用于求表达式的值,格式为:
expr 表达式
expr 是一个命令,命令后的每一项都要用空格隔开. 所以表达式中的每一项也要用<space> 隔开
需要对特殊字符进行转义处理,也是就用 \ 放在特殊符号前,(发现表达式运行错误时,可以试试转义)
对包含空格和其他特殊字符的字符串要用引号括起来
expr 的结果会输出在 stdout 中.(如果为逻辑关系表达式,则结果为真时,stdout输出1,否则输出0)
expr 的 exit code :如果为逻辑关系表达式,则结果为真时,exit code为0,否则为1.

字符串表达式

  1. length STRING: 返回STRING的长度
  2. index STRING CHARSET :返回 CHARSET 中任意单个字符在 STRING 中最前面的字符位置,下标从1开始.如果在STRING中完全不存在CHARSET中的字符,则返回0.
  3. substr STRING POSITION LENGTH: 返回STRING字符串中从POSITION开始,长度最大为LENGTH的子串.如果POSITION或LENGTH为负数,0或非数值,则返回空字符串.

算术表达式

只支持整数,算术表达式优先级低于字符串表达式,高于逻辑关系表达式.

+ -
加减运算.两端参数会转换为整数,如果转换失败则报错.

* / %
乘,除,取模运算.两端参数会转换为整数,如果转换失败则报错. *这个符号需要转义

() 可以改变优先级,但需要用反斜杠转义

10-expr-num.png
shell 主要是处理文件,管道,字符串的,并不针对数字处理.

逻辑表达式

|
如果第一个参数非空且非0,则返回第一个参数的值,否则返回第二个参数的值,但要求第二个参数的值也是非空或非0,否则返回0. 如果第一个参数是非空或非0时,不会计算第二个参数.(短路原则)

&
如果两个参数都非空且非0,则返回第一个参数,否则返回0. 如果第一个参为0或为空,则不会计算第二个参数.
这里一个 | 就相当于 c++ 中的两个|, 起逻辑表达式的作用,并且逻辑表达式的返回值不仅仅是 0 和 1

< <= = == != >= >
比较两端的参数,如果为true,则返回1,否则返回0.

==是 =的同义词.
“expr” 首先尝试将两端参数转换为整数,并做算术比较,如果转换失败,则按字符集排序规则做字符比较.

() 可以改变优先级,但需要用反斜杠转义
10-expr-logic.png

read 命令

可以看做是 cin
read命令用于从标准输入中读取单行数据.
当读到文件结束符时,exit code为1,否则为0.

参数说明:
-p: 后面可以接提示信息
-t:后面跟秒数,定义输入字符的等待时间,超过等待时间后会自动忽略此命令
但是后面的命令会继续执行
read 命令.png

echo 命令

echo 字符串会把这个字符串给输出
11-echo命令.png

格式化输出 printf

用的不多,所以偷个懒.放下 文档

test与[]

逻辑运算符

这里的逻辑运算符是 bash自己有的
之前的 | 和 & 是expr 自己定义的

&& 表示与,
|| 表示或
同样具有具有短路原则:
expr1 && expr2 :当expr1为假时,直接忽略expr2
expr1 || expr2 :当expr1为真时,直接忽略expr2
利用短路原则可以实现 if else 的效果
这里的判断的是表达式的返回结果(exit code)
0 为真, 其他为假(与C/C++中的定义相反)

test 命令

主要用于: 判断文件类型以及对变量做比较

test 命令用的是 exitcode 来返回结果

判断文件类型与权限

12-test-文件类型.png
12-test-1判断文件权限.png

整数间的比较

12-test-整数间的比较.png

字符串比较

12-test-字符串之间的比较.png

多重判断

12-test-多重判断.png

[ ] 符号

[]与test用法几乎一模一样,更常用于if语句中.
另外[[]]是[]的加强版,支持的特性更多
注意事项:

  • [] 内的每一项都要用空格隔开
  • [] 中括号内的变量,最好用双引号括起来
  • 中括号内的常数,最好用单或双引号括起来

12-[]符号.png

if else switch

if then 形式

if confition
then
    语句 1
    语句 2
    ...
fi

13-if-then.png

if else 格式

if condition
then
    语句1
    语句2
    ...
else
    语句1
    语句2
    ...
fi

13-if-else.png

多层if-elif-elif-else

if condition
then
    语句1
    语句2
    ...
elif condition
then
    语句1
    语句2
    ...
elif condition
then
    语句1
    语句2
else
    语句1
    语句2
    ...
fi

13-if-else-if.png

switch

case…esac形式
类似于C/C++中的switch语句.

case $变量名称 in
    值1)
        语句1
        语句2
        ...
        ;;  # 类似于C/C++中的break
    值2)
        语句1
        语句2
        ...
        ;;
    *)  # 类似于C/C++中的default
        语句1
        语句2
        ...
        ;;
esac

13-switch.png

0 评论

你确定删除吗?
1024
x

© 2018-2023 AcWing 版权所有  |  京ICP备17053197号-1
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标
请输入绑定的邮箱地址
请输入注册信息