Shell 学习过程中的一些记录
变量
变量定义
变量名与值使用一个等号 ‘=’ 连接
等号两边不能存在空格
1
2
|
$country =china # country: command not found
$country= china # country: command not found
|
变量名不能以数字开头,不能出现空格或标点符号
1
|
$2country=china # 2country=china:未找到命令
|
变量可以重复赋值
1
2
3
|
$foo=1
$foo=2
$echo $foo # 2
|
使用 declare
命令声明一些特殊类型的变量
常用参数:
-a
声明数组变量
-i
声明整数变量
-x
声明环境变量
-r
声明只读变量
1
2
3
4
|
$sum=1+2+3
$echo $sum # 1+2+3 (shell默认变量类型为字符串)
$declare -i sum=1+2+3
$echo $sum # 6
|
变量调用
1
2
3
4
5
6
7
8
9
10
11
12
|
$var_1=3
# 第一种方式 ${variable} (常用)
$echo ${var_1} # 3
# 第二种方式 $variable
$echo $var_1 # 3
# 计算变量长度
# 第一种方式 ${variable}
$echo ${#var_1} # 25
# 第二种方式
$len=`expr length "$var_1"`
$echo $len # 25
|
变量删除
一个伪概念,因为shell中对于未定义的变量一律返回空
因此删除一个变量有如下三种方法:
1
2
3
|
$unset variable
$variable=''
$variable=
|
输出变量
用户创建的变量仅可用于当前 Shell,
子 Shell 默认读取不到父 Shell 定义的变量。
为了把变量传递给子 Shell,需要使用export命令。
这样输出的变量,对于子 Shell 来说就是环境变量。
1
2
3
4
5
6
7
8
|
$foo=2
$bash # 新建子shell
$echo $foo # 返回空
$exit # 退出子shell
$export foo # 输出变量,使其变为当前shell的环境变量
$bash # 新建子shell
$echo $foo
2
|
子 shell 对变量的修改不影响父 Shell
1
2
3
4
5
6
|
$export foo=2
$bash # 新建子shell
$echo $foo # 2
$foo=3 # 在子shell重新赋值
$exit # 退出子shell
$echo $foo # 2
|
脚本参数传递
- $0 当前 Shell 的名称或者脚本名
- $1~$n 获取传入的参数
- $# 传递到脚本的参数数量
- $$ 当前 Shell 的 PID,可以用来命名临时文件
- $* 以一个单字符串显示所有向脚本传递的参数
- $? 上一个命令的退出码,0表示成功返回,其他任何值表明有错误
1
2
3
4
5
6
7
8
9
|
$ls notexist # ls: 无法访问 'notexist': 没有那个文件或目录
$echo $? # 2 错误码不固定
$echo $? # 0 上一个命令成功返回了,因此返回0
$echo $$ # 13597 当前shell的pid
$tempfile=tempfile.$$
$echo $tempfile # tempfile.13597
$echo $0 # bash
|
新建一个 test.sh
文件,写入如下内容
1
2
3
|
#!/bin/bash
echo "Hello World"
echo $0
|
执行一下
1
2
3
|
$bash ./test.sh
Hello World
./test.sh
|
命令替换
两种形式
1
2
3
4
5
|
$echo date # date
# `command` 使用反引号将变量包起来
$echo `date +%Y` # 2021
# $(command)
$echo $(date) # 2021年 4月21日 星期三 00时44分02秒 CST
|
数学运算
使用双括号进行整数运算
1
2
3
|
# (( )) 使用双括号将数学运算包起来
$echo $((20+30))
50
|
算术运算
- -eq 相等
- -ne 不相等
- -gt 大于
- -lt 小于
- -ge 大于等于
- -le 小于等于
1
2
3
4
|
$a=10
$b=20
$ if [ $a -eq $b ];then echo "true";else echo "false";fi
false
|
空格
- shell中使用空格区分不同的参数
- 如果参数之间有多个空格,shell会自动忽略
1
2
|
$echo this is a test
this is a test
|
引号
- 单引号包裹的内容会原样输出
- 双引号仍然可以保留变量内容
- 反引号:上面所说的命令替换
1
2
3
4
5
6
7
8
|
$country=china
$mycountry="mycountry is $country"
$echo $mycountry
mycountry is china # 双引号仍然可以保留变量内容
$mycountry='mycountry is $country'
$echo $mycountry
mycountry is $country # 单引号包裹的内容会原样输出
|
标准输入输出(重定向)
1
2
3
|
标准输入 (stdin) :代号为 0 ,使用 < 或 << 表示
标准输出 (stdout):代号为 1 ,使用 > 或 >> 表示
标准错误输出 (stderr):代号为 2 ,使用 2> 或 2>> 表示
|
其中,> 或 < 表示清空并写入,> > 或 < < 表示追加写入
标准输出,即指令执行后返回的正确信息
标准错误输出,即指令执行失败后返回的信息
标准输入,则是将原本需要由键盘输入的信息,改为通过文件内容输入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
$ ps a # 直接执行这个指令会输出如下标准输出
PID TTY STAT TIME COMMAND
25 pts/0 Ss 0:00 -bash
344 pts/0 R+ 0:00 ps a
$ ps a > ps.txt # 执行这个指令,原本应该在命令行输出的内容,会被保存到ps.txt文件中
$
$ cat ps.txt
PID TTY STAT TIME COMMAND
25 pts/0 Ss 0:00 -bash
344 pts/0 R+ 0:00 ps a
$ ps a 2> pserr.txt # 执行这个指令,因为只会将错误返回重定向,所以还是会输出下面的信息
PID TTY STAT TIME COMMAND
25 pts/0 Ss 0:00 -bash
344 pts/0 R+ 0:00 ps a
$ ps i 2> pserr.txt # ps命令没有 i 参数,所以直接执行会报错,使用 2> 可以将错误信息重定向到文件,因此终端看不到返回
$ cat pserr.txt
error: unsupported SysV option
Usage:
ps [options]
Try 'ps --help <simple|list|output|threads|misc|all>'
or 'ps --help <s|l|o|t|m|a>'
for additional help text.
$ ps i > pserr.txt # > 只能重定向正确返回,所以错误信息会直接返回在终端
error: unsupported SysV option
Usage:
ps [options]
Try 'ps --help <simple|list|output|threads|misc|all>'
or 'ps --help <s|l|o|t|m|a>'
for additional help text.
|
下面看一下标准输入的应用场景
1
|
$ mysql -uroot -p123456 < schema.sql
|
连接数据库之后,执行 schema.sql 文件中的语句