Shell Script基本语言

原创 2015年07月10日 09:47:47

第一个shell script程序

#!/bin/bash
# Program:
#    this is a test shell script
# 2015/07/10    zhubinqiang     Fitst release
echo "Welcome to shell script!"

脚本第一行 指定/bin/bash解释器执行,虽然以#开头 但不是注释
#开头的是单行注释

注释

# 这是单行注释1
# 这是单行注释2

Shell里面没有多行注释,小技巧实现多行注释

COMMENT_BLOCK=
if [ $COMMENT_BLOCK ]; then
===========================
echo "comment1"
echo "comment2"
echo "comment3"
===========================
fi

变量

a=15
version1=$(uname -r)
version2=`uname -r`
echo $a
echo ${version1}
echo $version2
PATH="$PATH:$HOME/bin"
export PATH
unset a
  1. 变量名=变量, 两边没有空格的。 空格在shell中有特殊用途,分开的话会解释成【命令 参数 参数】的形式
  2. 变量名区分大小写。 name 与 Name 是两个变量
  3. 变量有空格的话要用单引号” 或 双引号 “” 将变量内容结合起来
  4. 上式中$a 与 ${a} 是相同效果的。使用${a} 避免出错
  5. ${a}’ 是强引用 输出${a}。”${a}”是弱引用,输出变量值
  6. export 使变量成为环境变量
  7. unset 取消变量
  8. shell变量是不区分类型的,变量值都是字符串。Bash允许整数比较和运算操作,但变量中只有数字

算术运算

算术运算符

操作符 描述
+ 加法运算
- 减法运算
* 乘法运算
/ 除法运算
% 求余运算
** 幂运算
+= 加等于
-= 减等于
*= 乘等于
/= 除等于
%= 取模等于

let 运算

a=1
let a=a+1
echo $a           # 2
let a+=1
echo $a           # 3 
let "a = a + 2"
echo $a           # 5

$((…))运算

a=1
a=$((a+1))
echo $a

expr 运算

a=1
b=`expr $a + 1`
echo $b

if … else … 判断语句

a="hello"
if [ "$a" == "hello" ]; then
    echo "Hello, how are you."
elif [ "$a" == "" -o "$a" == '?' ]; then
    echo "what?"
elif [ "$a" == 'y' ] || [ "$a" == 'Y' ]; then
    echo "Yes"
else
    echo "I don't understand you."
fi

[ 左右两边有一个空格, == 左右两边有一个空格,] 左边有一个空格

算术与字符串测试

操作 描述 操作 描述
算术比较 中括号[…]结构 字符串比较 中括号[…]结构
-eq 等于 =/== 等于
-ne 不等于 != 不等于
-lt 小于 \< 小于(ASCII) *
-le 小于等于
-gt 大于 \> 大于(ASCII)*
-ge 大于等于
-z 字符串为空
-n 字符串不为空
算术比较 双括号((…))结构 条件判断
> 大于 -a 两个条件同时成立
>= 大小于等于 -o 任何一个条件成立
< 大于 !
<= 小于等于

*如果在双中括号[[ … ]]测试中的话,那么不需要转义符\

文件测试

操作 描述 操作 描述
-e 文件是否存在 -s 文件大小不为0
-f 是一个标准文件
-d 是一个目录 -r 文件具有读的权限
-h 文件是一个符号链接 -w 文件具有写的权限
-L 文件是一个符号链接 -x 文件具有执行权限
-b 文件是一个块设备
-c 文件是一个字符设备 -g 设置了sgid标记
-p 文件是一个管道 -u 设置了suid标记
-S 文件是一个socket -k 设置了”粘贴位”
-t 文件与一个终端相关联
-N 从这个文件最后一次被读取之后,它被修改过 F1 -nt F2 文件F1比文件F2新
-O 这个文件的宿主是你 F1 -nt F2 文件F1比文件F2旧
-G 文件的组id与你所在的组相同 F1 -nt F2 文件F1和F2都是同一个文件的硬链接
! “非”(翻转上边的测试结果)

Case

像C语言中的switch… case…

a="hello"
case $a in
"hello")
    echo "Hello, how are you." ;;
"")
    echo "what?" ;;
*)
    echo "I don't understand you." ;;
esac

while 循环

i=0
s=0
while [ "$i" -le 100 ];do
    s=$((s+i))
    i=$((i+1))
done
echo "1 + 2 + 3 + ... + 100 = $s"

until 循环

i=0
s=0
until [ "$i" -gt 100 ]; do
    s=$((s+i))
    i=$((i+1))
done
echo "1 + 2 + 3 + ... + 100 = $s"

for 循环

for i in Tom Jack John; do
    echo $i
done

for i in $(seq 1 5); do
    echo $i
done

for i in {1..5}; do
    echo $i
done

for((i=0; i<5; i++)); do
    echo $i
done

数组

array=(5 4 3 2 1)
echo ${array[0]}     # 第一个元素

len=${#array[*]}     # 数组长度
for((i=0; i<$len; i++));do
    echo ${array[$i]}
done

for i in ${!array[@]}; do
    echo ${array[$i]}
done

函数

函数定义

function function_name {
    command...
}

function function_name() {
    command...
}

function_name() {
    command...
}

使用函数

function sayHello() {
    local name=$1
    echo "Hello $name"
    return 0
}

sayHello "Tom"

return返回的是状态码。 0 表示成功, 非0表示失败。

如果要返回值用echo

function sum(){
    local a=$1
    local b=$2
    local s=$((a+b))
    echo $s
}

s=`sum 2 3`
echo $s

用shift 获取参数

function sum(){
    local a=$1
    shift
    local b=$1
    local s=$((a+b))
    echo $s
}

s=`sum 2 3`
echo $s

I/O操作

终端输入,并赋值

read -p "Your name(within 30s):" -t 30 named
echo $named

输出多行

cat << EOF
comment1
comment2
comment3
EOF

I/O重定向

COMMAND > filename             # 重定向stdout到文件filename
COMMAND 1> filename            # 重定向stdout到文件filename
COMMAND >> filename            # 重定向stdout并追加到文件filename
COMMAND 1>> filename           # 重定向stdout并追加到文件filename
COMMAND 2> filename            # 重定向stderr到文件filename
COMMAND 2>> filename           # 重定向stderr并追加到文件filename
COMMAND &> filename            # 将stdoutstderr都重定向到filename
COMMAND &>> filename           # 将stdoutstderr都重定向并追加到filename
COMMAND > filename 2>&1        # 将stdoutstderr都重定向到filename
COMMAND >> filename 2>&1       # 将stdoutstderr都重定向并追加到filename

管道操作

COMMAND1 | COMMAND2 | COMMAND3
cat /etc/passwd | grep "root" | awk -F":" '{print $1}' 

管道操作是由前面的stdin传递过来的。 stderr不会传过去

特殊Shell变量

变量 含义
$0 脚本名字
$1 位置参数 #1
$9 位置参数 #9
${10} 位置参数 #10
$# 位置参数的个数
“$*” 所有的位置参数(作为单个字符串)
“$@” 位置参数的个数(作为独立的字符串)
${#*} 传递到脚本中的命令行参数的个数
${#@} 传递到脚本中的命令行参数的个数
$? 返回值
$$ 脚本的进程IP(PID)
$- 传递到脚本中的标志(使用set)
$_ 之前命令的最后一个参数
$! 运行在后头的最后一个作业的进程ID(PID)

@”

系统环境变量

变量 含义
$IFS 保存了用于分割输入参数的分割字符,默认识空格
$HOME 当前用户的根目录路径
$PATH 可执行文件的搜索路径
$PS1 第一个系统提示符
$PS2 第二个系统提示符
$PWD 当前工作路径
$EDITOR 系统的默认编辑器名称
$BASH 当前Shell的路径字符串
$EUID “有效”用户ID

字符串操作

表达式 描述
${#string} $string的长度
${string:position} $string中,从position开始提取字串
${string:position:length} $string中,从position开始取长度为length的字串
${string#substring} 从变量$string的开头,删除最短匹配$substring的字串
${string##substring} 从变量$string的开头,删除最长匹配$substring的字串
${string%substring} 从变量$string的结尾,删除最短匹配$substring的字串
${string%%substring} 从变量$string的结尾,删除最长匹配$substring的字串
${string/substring/replacement} 使用$replacement,代替第一个匹配的$substring
${string//substring/replacement} 使用$replacement,代替所有匹配的$substring
${string/#substring/replacement} 如果$string的前缀匹配$substring,那么就用$replacement来代替匹配的$substring
${string/%substring/replacement} 如果$string的后缀匹配$substring,那么就用$replacement来代替匹配的$substring
expr match “$string” ‘$substring’ 匹配$string开头的$substring*的长度
expr “$string” : ‘$substring’ 匹配$string开头的$substring*的长度
expr index “$string” $substring $sttring中匹配到$substring的第一个字符出现
expr substr $string $position $length $string中从位置$position开始提取长度为$length的字串
expr match “$string” ‘\{$substring}\’ $string的开头位置提取$substring*
expr “$string” : ‘\($substring)\’ $string的开头位置提取$substring*
expr match “$string” ‘.*\($substring)\’ $string的结尾提取$substring*
expr “$string” : ‘.*\($substring)\’ $string的结尾提取$substring*

* $substring 是一个正则表达式

结构汇总

操作 描述
中括号
if [ Condition ] 测试结构
if [[ Condition ]] 扩展的测试结构
Array[1]=element1 数组初始化
[a-z] 正则表达式的字符范围
大括号
${variable} 参数替换
${!variable} 间接变量引用
{ command1; command2; … commandN; } 代码块
{string1, string2, string3} 大括号扩展
小括号
( command1; command2 ) 子shell中执行的命令组
Array=(element1 element2 emement3) 数组初始化
result=$(COMMAND) 在子shell中执行命令,并将结果赋值给变量
>(COMMAND) 进程替换
<(COMMAND) 进程替换
双小括号
(( var = 78 )) 整型运算
var=$(( 20 + 5 )) 整型运算,并将结果赋值给变量
引号
$variable” “弱”引用
‘string’ “强”引用
后置引用
result=`COMMAND` 在子shell中运行命令,并将结果赋值给变量

globbing

*: 匹配任意长度的任意字符
a*b 匹配 ab, a123b

?: 匹配任意单字符
a?b 匹配 a1b, a2b

[]: 匹配指定范围内的 任意单字符
[abc], [a-z], [0-9]

[^]: 匹配任意范围外的任意单字符
[^a-z0-9]

字符合集
[[:space:]]: 所有空白字符
[[:punct:]]: 所有标点字符
[[:lower:]]: 小写字母
[[:upper:]]: 大写字母
[[:alpha:]]: 所有字母
[[:digit:]]: 数字
[[:alnum:]]: 字母数字

举例:在/urs/lib/下列出 以l开头,中间有数字,结尾是小写字母
ls /usr/lib/l*[[:digit:]]*[[:lower:]]

echo -e '\033[32mHello\033[0m'

\033[
\033: Ctrl
单个数字:控制字体
3#: 3表示控制其前景色, #是一个数字
4#: 4表示控制其背景色, #是一个数字
组合使用,彼此间使用;分隔
m: 是固定格式
\033[0m: 控制符到此结束

版权声明:本文为博主原创文章,未经博主允许不得转载。

linux shell是一种极为丑陋的语言

linux shell是一种极为丑陋的语言。 shell是一以命令行为主的语言,这门语言的丑陋体现在它的语法不规范上。举例说明。 一、空格的使用 linux shell里面最令人困惑的莫...

Netty入门到精通课程|物联网视频教程

《物联网核心技术之Netty入门到精通课程》 本课程由学途无忧网独家提供 课程来源于:http://www.xuetuwuyou.com/course/14 课程内容介绍...

linux shell是一种极为丑陋的语言

linux shell是一种极为丑陋的语言。 shell是一以命令行为主的语言,这门语言的丑陋体现在它的语法不规范上。举例说明。 一、空格的使用 linux shell里面最令人困惑的莫...

Shell Script语言教程~

Shell Script语言教程 《目录》 □前言 □将文字档设为可执行的Shell Script □Script的基本结构及观念 □Bourne Shell 一、变量 二、执行命令 ...

shell script语言教程

  • 2012年01月30日 03:29
  • 203KB
  • 下载

shell script 语言教程

  • 2009年09月22日 17:38
  • 157KB
  • 下载

C语言实现基本排序算法----排序(直接插入排序,SHELL排序,冒泡排序,快速排序,简单选择排序,堆排序)

//C语言程序----排序(直接插入排序,SHELL排序,冒泡排序,快速排序,简单选择排序,堆排序)//调试成功运行#include "iostream"#include "stdlib.h"#inc...

编程语言基本用法总结(Shell,Python,C/C++)

1. Shell  脚本执行目录声明: #!/bin/bash 数据结构: val_str="string" #定义字符串变量 val_int=1 #定义整形变量 arry_str...

shell script

  • 2012年04月26日 11:26
  • 178B
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Shell Script基本语言
举报原因:
原因补充:

(最多只允许输入30个字)