Linux shell 入门

shell 是弱类型语言,这跟 PHP 等弱类型脚本语言类似。
参考资料
在线编辑器

1. 语法

shell 以 # 开头的行就是注释,只有单行注释,没有多行注释,只能每一行加一个 # 号。

1.1 变量

shell 中使用 echo 打印内容,默认输出到 STDOUT(即终端窗口)中。

用户自定义变量

定义变量

定义变量时,变量名不加美元符号($)。注意,变量名和等号之间不能有空格

除了显式地直接赋值,还可以用语句给变量赋值。

a=666
s="hello"usr var

shell 中可以使用命令,语法为 $(command)

c=$(pwd)	# /root/shell
d=$(ls /)	# bin boot data dev etc ... root run sbin srv sys tmp 

使用变量

使用变量时支持两种语法,都需要在变量名前面加美元符号:

  • $var:在变量名前加 $ 符号即可使用变量
  • ${var}:将变量放在 ${} 的大括号中,需要识别边界时,必须使用大括号
a=666
s="hello"
echo $a
echo ${a}			# 一般情况下,大括号可用可不用
echo "$a"
echo "${s}world"	# 需要识别边界时,必须使用大括号
echo "$aworld"		# 这种情况无法识别边界,输出为空

为了帮助解释器识别变量的边界,变量名的外面可以添加花括号。推荐给所有变量加上花括号。

重定义变量

已定义的变量,可以被重新定义,如:

a=666
echo $a

a="hello"
echo $a

shell 中的变量类型可以改变。

环境变量

Linux 系统有多个内置的环境变量(通过 env 命令可以查看所有环境变量),且用户可以添加或删除环境变量。注意,环境变量区分大小写。

最常见的 PATH 环境变量,用冒号分割路径:

echo $PATH			#/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PATH=$PATH:/root
echo $PATH			#/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root

特殊变量

[root@VM_139_38_centos shell]# ./test.sh a b "c d" e
./test.sh
a
4
./test.sh: line 8: asdf: command not found
127
a b c d e
a b c d e
[root@VM_139_38_centos shell]# cat test.sh 
#!/bin/bash

echo $0
echo $1
echo $#

asdf
echo $?
echo $*
echo $@
[root@VM_139_38_centos shell]# cat test.sh 
#!/bin/bash

echo $0
echo "-- \$* 演示 ---"
for i in "$*"; do
    echo $i
done

echo "-- \$@ 演示 ---"
for i in "$@"; do
    echo $i
done
[root@VM_139_38_centos shell]# /root/test/shell/test.sh a b "c d" e
/root/test/shell/test.sh
-- $* 演示 ---
a b c d e
-- $@ 演示 ---
a
b
c d
e

$n

在脚本中,$0 变量表示当前脚本名,$1$9 表示执行脚本时传入的第一个至第九个参数。如果参数占两位数字,需要用大括号,例如 ${11}

$#

获取所有输入参数的个数,可以用于循环。

类似 ${#a} 可以计算字符串的字符个数。

$*$@

  • $*:代表命令行中所有的参数,把所有参数看成一个整体
  • $@:代表命令行中所有的参数,把每个参数区分对待,可以在循环中取出

$?

最后一条执行的命令的返回码。0表示最后一个命令正确执行,非0表示失败。

[root@VM_139_38_centos ~]# $?
-bash: 0: command not found
[root@VM_139_38_centos ~]# echo $?
127
[root@VM_139_38_centos ~]# ls
acme  mysql  nohup.out  swoole  test  tmux-client-14353.log
[root@VM_139_38_centos ~]# echo $?
0

$$

脚本运行的当前进程ID号。

脚本入参的判断

为了防止错误,可以在脚本中添加对入参的判断语句:

if [ ! -n "$1" ]; then
    echo "no param input"
    exit
else
	param=$1
fi

1.2 字符串

shell 中的字符串可以用单引号,可以用双引号,也可以不用引号。单双引号的区别跟 PHP 类似。

单引号

str='hello world'

单引号字符串的限制:

  • 单引号中不识别变量,原样输出
  • 单引号字串中不能出现单引号(对单引号使用转义符后也不行)

双引号

str='hello world'
echo "你好,世界!\"$str\""	#你好,世界!"hello world"

双引号特点:

  • 双引号中可以识别变量
  • 双引号中可以识别转义字符

字符串操作

拼接字符串

shell 中字符串直接连到一起即可,不需要任何连接字符。也可以将字符串变量放在双引号字符串中的合适位置。

s="world"
s1="hello, "$s" !"
s2="hello, ${s} !"

echo $s $s

获取字符串长度:

直接用 ${#字符串变量名} 就可以获得字符串长度:

s="hello"
echo ${#s} # 5

提取子字符串

直接用 ${字符串变量名:start:length} 就可以获得子字符串:

s="hello world"
echo ${s:1:4} #输出:ello

1.3 数学运算

shell 中进行数学运算的方法挺多,下面一一列举。

简单运算

let 命令、[]、(()) 的使用方法类似。

1. let 命令

let 命令是 bash 内置命令,可以实现简单的算术运算和逻辑运算。可以使用 help let 命令查看具体用法。常见用法:

#!/bin/sh

i=10
echo $i

let i=i+10
echo $i 		#20

let "i=i+100"
echo $i 		#120

2. []

i=10

i=$[i+10]
echo $i

i=$[i+100]
echo $i

3. (())

i=10

i=$((i+10))
echo $i

i=$((i+100))
echo $i

高级运算

1. expr

使用 expr 时,变量与算术运算符之间需要加空格,且乘号需要转义。

i=10

i=`expr $i + 10`	#20
echo $i

i=`expr $i + 100`	#120
echo $i

不加空格时,情况如下:

i=10

i=`expr $i + 10`	#10+10
echo $i

i=`expr $i + 100`	#10+10+100
echo $i

2. bc 命令

bc 命令支持浮点运算和数学函数调用。

i=10
j=3

m=`echo "scale=9; $i / $j" | bc` #3.33333
echo $m

1.4 数组

Bash Shell 只支持一维数组,初始化时不需要定义数组大小(与 PHP 类似),元素下标由0开始。

Shell 数组用括号来表示,元素用"空格"分割,语法格式如下:

array_name=(value1 ... valuen)

array_name[0]=value0

读取数组
读取数组元素值的一般格式是:

${array_name[index]}

使用 @ 或 * 可以获取数组中的所有元素,用 # 获取数组的长度,例如:

echo "所有元素为:${my_array[*]}"
echo "所有元素为:${my_array[@]}"

echo "数组长度为:${my_array[#]}"

示例:

arr=(1 2 hello "h h h")
for i in ${arr[@]}
do
	echo $i
done

输出为:

1
2
hello
h
h
h

1.5 控制语句

控制语句使用 if/else/fi 语法,语法:

if condition
then
	command1 
	command2
	...
	commandN
elif condition2
	command2
else
	commandN
fi

示例:

if [[ 3 > 7 ]]; then
	echo "3 > 7"
else
	echo "3 <= 7"
fi

可以使用的数值比较符号有:

比较符 描述
n1 -eq n2 检查 n1 是否等于 n2
n1 -ge n2 检查 n1 是否大于或等于 n2
n1 -gt n2 检查 n1 是否大于 n2
n1 -le n2 检查 n1 是否小于或等于 n2
n1 -lt n2 检查 n1 是否小于 n2
n1 -ne n2 检查 n1 是否不等于 n2

可以使用的字符串比较:

比较符 描述
str1 = str2 检查 str1 是否和 str2 相同
str1 != str2 检查 str1 是否和 str2 不同
str1 < str2 检查 str1 是否比 str2 小
str1 > str2 检查 str1 是否比 str2 大
-n str1 检查 str1 的长度是否非 0
-z str1 检查 str1 的长度是否为 0

文件比较:

比较符 描述
-d file 检查 file 是否存在并是一个目录
-e file 检查 file 是否存在
-f file 检查 file 是否存在并是一个文件
-r file 检查 file 是否存在并可读
-s file 检查 file 是否存在并非空
-w file 检查 file 是否存在并可写
-x file 检查 file 是否存在并可执行
-O file 检查 file 是否存在并属当前用户所有
-G file 检查 file 是否存在并且默认组与当前用户相同
file1 -nt file2 检查 file1 是否比 file2 新
file1 -ot file2 检查 file1 是否比 file2 旧

1.6 循环语句

for

for 循环语法一(for in 格式):

for var in item1 item2 ... itemN
do
	command1
	command2
	...
	commandN
done

写成一行:

for var in item1 item2 ... itemN; do command1; command2… done;

语法二(C 语言风格):

for (( EXP1; EXP2; EXP3 ))
do
	command1
	command2
	command3
done

示例:

sum = 0
for ((i = 0; i < 10; i++)); do
	sum = $[sum + $i]
done
echo $sum

while

while 循环语法:

while condition
do
	command
done

无限循环:

while :
do
	command
done

1.7 函数

函数定义

shell 中可以自定义函数,然后在shell脚本中可以随便调用。函数定义格式如下:

[ function ] funname [()]
{
    action;
    [return int;]
}

说明:

1、函数定义的关键字 function 可用可不用
2、参数返回值可用可不用。如果不加,将以最后一条命令运行结果,作为返回值。如果加,return 的数值范围是 0-255

下面的例子定义了一个函数并进行调用:

#!/bin/bash

myFun() {
	echo "hello function"
}

myFun

函数参数

Shell 中调函数时可以传参。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数…

带参数的函数示例:

myFun() {
	echo $#
	echo $1
	echo $2
	echo $0
}

myFun 1 "hello function"

输出为:

2
1
hello function
/tmp/820834436/main.sh

2. 文件操作

2.1 文件读取

2.2 文件写入

2.3 文件包含

Shell 可以包含外部脚本,可以很方便的封装一些公用的代码作为一个独立的文件。被包含的文件 test1.sh 不需要可执行权限。语法格式如下:

. filename   # 注意点号(.)和文件名中间有一空格

source filename

3. sed 流编辑

4. 模块

4.1 工具模块

4.2 流程模块

5. 输入和菜单

5.1 获取输入

5.2 菜单

posted on 2018-04-12 23:20  kikajack  阅读(125)  评论(0编辑  收藏  举报