Shell脚本编程——上

文章目录
  1. 1. Shell简介
  2. 2. start
    1. 2.1. helloworld
    2. 2.2. echo
    3. 2.3. printf
    4. 2.4. 交互
    5. 2.5. 重定向
    6. 2.6. 包含脚本
  3. 3. 变量
    1. 3.1. 基本变量
    2. 3.2. 特殊变量
    3. 3.3. 变量替换
    4. 3.4. 命令替换
    5. 3.5. 字符串
    6. 3.6. 数组
  4. 4. 源码分享
  5. 5. 书签

Shell简介

Shell本身是一个用C语言编写的程序,它是用户使用Unix/Linux的桥梁,用户的大部分工作都是通过Shell完成的。Shell既是一种命令语言,又是一种程序设计语言。作为命令语言,它交互式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。

它虽然不是Unix/Linux系统内核的一部分,但它调用了系统核心的大部分功能来执行程序、建立文件并以并行的方式协调各个程序的运行。因此,对于用户来说,shell是最重要的实用程序,深入了解和熟练掌握shell的特性极其使用方法,是用好Unix/Linux系统的关键。

可以说,shell使用的熟练程度反映了用户对Unix/Linux使用的熟练程度。

Shell有两种执行命令的方式:
交互式(Interactive):解释执行用户的命令,用户输入一条命令,Shell就解释执行一条。
批处理(Batch):用户事先写一个Shell脚本,其中有很多条命令,让Shell一次把这些命令执行完,而不必一条一条地敲命令。

Shell脚本和编程语言很相似,也有变量和流程控制语句,但Shell脚本是解释执行的,不需要编译,Shell程序从脚本中一行一行读取并执行这些命令,相当于一个用户把脚本中的命令一行一行敲到Shell提示符下执行。

start

helloworld

1、新建helloworld.sh,vim helloworld.sh内容为:

1
2
#!/bin/bash
echo "Hello World !"

#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种Shell。echo命令用于向窗口输出文本。

2、添加执行权限
chmod +x helloworld.sh

3、执行脚本
./helloworld.sh

PS:输入gg跳到首行,.,$d,表示从当前行到末行全部删除掉。或者,1,$d,表示从首行到末行全部删除掉。

echo

echo是Shell的一个内部指令,用于在屏幕上打印出指定的字符串。

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
#!/bin/bash

# 显示转义字符
echo "\"It is a test\""

# 显示变量
name="VoidKing"
echo "Welcome, $name"

# 变量与其它字符相连时需要使用大括号
month=8
echo "${month}-1-2009"

# 显示换行
echo -e "OK!\n"
echo "It is a test"

# 显示不换行
echo -e "OK!\c"
echo "It is a test"

# 显示结果重定向至文件
echo "It is a test" > myfile

# 原样输出字符串
echo '$name\"'

# 显示命令执行结果
echo `date`

printf

printf 命令用于格式化输出, 是echo命令的增强版。它是C语言printf()库函数的一个有限的变形,并且在语法上有些不同。

注意:printf 由 POSIX 标准所定义,移植性要比 echo 好。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/bash

# format-string为双引号
printf "%d %s\n" 1 "abc"

# 单引号与双引号效果一样
printf '%d %s\n' 1 "abc"

# 没有引号也可以输出
printf %s abcdef

# 一个格式多个参数
printf %s abc def
printf "%s\n" abc def
printf "%s %s %s\n" a b c d e f g h i j

# %s默认为空,%d默认为0
printf "%s and %d \n"

# 如果以%d的格式来显示字符串,那么会有警告,并且默认置为 0
printf "always prints %s,%d\n" Hello Shell

交互

使用 read 命令从 stdin 获取输入并赋值给 PERSON 变量,最后在 stdout 上输出。

1
2
3
4
5
#!/bin/bash

echo "What is your name?"
read PERSON
echo "Hello, $PERSON"

重定向

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash

# stdout重定向到file
ls -l > file
ls -l >> file

# stdout和stderr合并后重定向到myfile
ls -l > myfile 2>&1
ls -l >> myfile 2>&1

# 屏蔽 stdout 和 stderr
ls -l > /dev/null 2>&1
1
2
3
4
5
6
#!/bin/bash

cat << EOF
My name is VoidKing.
I'm good at programming.
EOF

包含脚本

1
url="http://www.voidking.com"
1
2
3
4
5
6
#!/bin/bash

. ./helloworld.sh
source ./helloworld.sh
. ./url.sh
echo $url

变量

基本变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/bash

# 定义变量
your_name="voidking"
your_age=25

# 显示变量
echo -e "your name is ${your_name} \n welcome to shell world"
echo "your age is ${your_age}"

your_email="voidking@qq.com"

# 设置your_email为只读变量
readonly your_email

echo "your email is $your_email"

your_address="中国吉林长春"

# 删除变量
unset your_address

注意,变量名和等号之间不能有空格,这可能和我们熟悉的所有编程语言都不一样。
shell里没有多行注释,只能每一行加一个#号。

上面的脚本中,我们使用了一些中文。在CentOS7.2中,如果出现乱码,那么,我们需要添加CentOS7.2的中文支持。
locale,显示LANG=C。

vim /etc/locale.conf,修改locale.conf如下:

1
2
3
4
LANG="zh_CN.UTF-8"
LANGUAGE="zh_CN.UTF-8:zh_CN.UTF-8:zh_CN"
SUPPORTED="zh_CN.UTF-8:zh_CN:zh:en_US.UTF-8:en_US:en"
SYSFONT="lat0-sun16"

locale,显示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
LANG=zh_CN.UTF-8
LC_CTYPE="zh_CN.UTF-8"
LC_NUMERIC="zh_CN.UTF-8"
LC_TIME="zh_CN.UTF-8"
LC_COLLATE="zh_CN.UTF-8"
LC_MONETARY="zh_CN.UTF-8"
LC_MESSAGES="zh_CN.UTF-8"
LC_PAPER="zh_CN.UTF-8"
LC_NAME="zh_CN.UTF-8"
LC_ADDRESS="zh_CN.UTF-8"
LC_TELEPHONE="zh_CN.UTF-8"
LC_MEASUREMENT="zh_CN.UTF-8"
LC_IDENTIFICATION="zh_CN.UTF-8"
LC_ALL=

特殊变量

1
2
3
4
5
6
7
8
9
#!/bin/bash

echo "Process ID: $$"
echo "File Name: $0"
echo "First Parameter: $1"
echo "Second Parameter: $2"
echo "Quoted Values: $@"
echo "Quoted Values: $*"
echo "Total Number of Parameters: $#"

变量替换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/bin/bash

echo ${var:-"Variable is not set"}
echo "1 - Value of var is ${var}"

echo ${var:="Variable is not set"}
echo "2 - Value of var is ${var}"

unset var
echo ${var:+"This is default value"}
echo "3 - Value of var is $var"

var="Prefix"
echo ${var:+"This is default value"}
echo "4 - Value of var is $var"

echo ${var:?"Print this message"}
echo "5 - Value of var is ${var}"

命令替换

1
2
3
4
5
6
7
8
#!/bin/bash

DATE=`date`
echo "Date is $DATE"
USERS=`who | awk '{print $1}'`
echo "Logged in user are $USERS"
UP=`date ; uptime`
echo "Uptime is $UP"

字符串

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
#!/bin/bash

# 单引号字符串中的变量无效,任何字符都会原样输出
# 单引号字串中不能出现单引号(对单引号使用转义符后也不行)
str='this is a string'

# 双引号里可以有变量,可以出现转义符
str="Hello, I know your are \"$your_name\"! \n"


# 拼接字符串
your_name="voidking"
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting $greeting_1

# 获取字符串长度
string="abcd"
echo ${#string}

# 提取子字符串
string="alibaba is a great company"
echo ${string:1:4}

# 查找子字符串
string="alibaba is a great company"
echo `expr index "$string" is`

数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/sh

name[0]="VoidKing0"
name[1]="VoidKing1"
name[2]="VoidKing2"
echo "Index0: ${name[0]}"
echo "Index1: ${name[1]}"

echo "All names: ${name[*]}"
echo "All names: ${name[@]}"

age=(24 25 26)
age[2]=25

# 取得数组元素的个数
name_length=${#name[@]}
age_length=${#age[*]}
echo "name_length: $name_length,age_length: $age_length"

# 取得数组单个元素的长度
lengthn=${#name[0]}
echo "Index0 length: $lengthn"

源码分享

https://github.com/voidking/shell.git

书签

Linux Shell脚本教程:30分钟玩转Shell脚本编程
http://c.biancheng.net/cpp/shell/