Shell Script基本语言

第一个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: 控制符到此结束

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值