基础篇
基本语法
指定脚本解释器
#!
#!/bin/sh
#!/bin/bash
使脚本拥有执行权限
chmod +x
.sh文件第一行必须指定解释器 或者使用 时直接指定
#!决定了脚本可以像一个独立的可执行文件一样执行 而不用在终端输入 sh bash python等等
注释
单行注释 #号
多行注释
:<<EOF
EOF
echo
echo会自动添加换行符
echo "输出字符串"
#输出含变量的字符串
name=zp
echo "hello, \"${name}\""
# Output: hello, "zp"
#输出不换行字符串
echo -e "" -e开启转义字符 开了-e才会识别换行
\c 表示不换行
#输出重定向文件 将输出到文件里面
echo "test" > test.txt
#输出当前目录 `` 识别基本命令 获取结果
echo `pwd`
printf
# printf 不会输出换行符
变量
命名规则
#只能使用英文字母 数字 下划线 收割字符不能数字开头
#中间不能有空格
#不能使用标点
#不能使用bash里面的关键字
声明变量
# 语法形式为 ${var} 和 $var
world="hello"
echo ${word}
readonly word #只读变量
unset word #删除变量
变量类型
#局部变量 仅在脚本内助有效的变量,其他程序和脚本无法访问
#环境变量 当前shell会话的所有程序和脚本 都有效 和局部变量创建很想 使用 export关键字
#常见的环境变量
$HOME 当前用户目录
$PATH 用分号分割的目录列表,shell回到这些目录查找命令
$PWD 当前工作目录
$RANDOM 0到32767之间的整数
$UID 数值类型 当前用户的用户ID
$PS1 主要系统输入提示符
$PS2 次要系统输入提示符
字符串
单引号和双引号
#单引号的特点
不识别变量
里面不能出现单独的引号 转义字符也不行 可以成对出现 作为拼接字符串使用
#双引号
识别变量
可以使用转义字符
基本使用
#获取变量长度
text="123456"
${#text}
#截取字符串
text="12345"
echo ${text:2:2}
输出34 相当于剪切了
#查找子字符串
text="hello"
echo `expr index "${text}" ll`
查找 ll 在text里面的起始位置
数组
基本使用
#创建数组
nums =({2}=2 {0}=0)
color(red yellow "dark blue")
#访问数组
echo ${nums[1]}
#访问所有元素
echo ${color[*]}
echo ${color[{@]}
@会将元素扩展为一个单独的参数 中间的空格得以保留
#访问部分元元素
echo ${color{@}:2:0}
#长度
echo ${#nums[*]}
添加
colors=(white "${colors[@]}" green black)
echo ${colors[@]}
删除
unset colors[0]
运算符
算术运算符
#加减乘除 取余 使用 expr
expr $x+$y
#= 赋值 ==比较
x=$y
[#x==$y]
x=10
y=20
echo "x=${x}, y=${y}"
#这里[[ 中间需要空格 ]]
if [[ ${x} != ${y} ]]
then
echo "${x} != ${y}"
fi
关系运算符
-eq 是够相等 是返回true
-ne 是否不相等 否返回true
-gt A大于B 则true
-lt A小于B 则true
-ge A大于B 则true
-le A小于B 则true
布尔运算符
! 反过来 true变false 反之
-o 有一个true则true 相当于 or
-a and运算符
逻辑运算符
&& 逻辑AND
|| 逻辑 OR
字符串运算符
= 字符串是否相当
!=
-z 为0则true
-n 不为0则true [ -n $a ]
str 非空则true [ $a ]
文件测试运算符
-b file 块设备文件则true
-c file 字符设备文件 则true
-d file 目录则true
-f file 普通文件(不是目录,也不是设备文件)则true
-g file 设置了 SGID则 true
-k file 设置了 沾着位这true
-p file 有名管道则true
-u 设置了SUID则true
-r file 文件可读则true
-w file
-x file 可执行
-s file 是否为空
-e file 文件或目录存在则 true
file = "/etc/hosts"
if [[ -r ${file} ]]:then
else
fi
控制语句
条件语句
bash中 [[]] sh中是[] fi标志代码结束
if then elif else fi
exec
case ${oper} in
"+")
val=`expr ${x} + ${y}`
echo "${x} + ${y} = ${val}"
;;
"-")
echo ""
;;
esac
命令块之间要用;;分割
循环语句
for arg in elem1 elem2 elemN
do
done
#参数arg 依次被赋值为 elem1 elem2 可以用大括号扩展 不过需要加分号
for arg in {1..5};do
done
for ((i=0;i<5;i++));do
then
例子
DIR=/home/zp
for FILE in ${DIR}/*.sh; do
mv "$FILE" "${DIR}/scripts"
done
# 将 /home/zp 目录下所有 sh 文件拷贝到 /home/zp/scripts
#do和while一行的时候需要加分号
while 循环
while [[ 循环条件 ]];do
done
until [[ ]];do
done
#一般用来打印序列到屏幕,用户输入 使用break退出 continue跳过本次循环
select answer in elem1 elem2
do
done
函数
function 关键词可以不要 不写return的话 返回最后一条语令的结果 值类型只能返回0-255
返回值可以调用函数之后 $? 获得
使用之前必须定义, 然后调用 也就是 写了之后要调用一下
function funname [()]{
}
位置参数
$0 脚本名称
$1 ... $9 第一到第九个参数列表
${10} ... ${N} 10到N个参数列别
$* or $ $@ 除了 $0之外所有位置参数
$# 不包括$0在内的位置参数的个数
$FUNCNAME 在函数内部有值
函数处理参数
$# 返回参数个数
$* 返回所有参数
$$ 脚本运行的当前进程ID
$! 后台运行的最后一个进程的ID
$@ 返回所有参数
$- 返回shell使用的当前选项 与set命令功能相同
$? 函数返回值
扩展
echo {00..8..2} 00 02 04 06
echo {0..5} 0 1 2 3 4 5
算术扩展 $(( ))
命令置换 ``或者 $()包围的时候会被之后 命令 被包围的时候会
now= `date`+%T
echo $now 输出时间
流和重定向
输入输出
0 stdin 标准输入
1 stdout 标准输出
2 strerr 标准错误输出
重定向
> 重定向输出
&> 重定向输出和错误输出
&>> 以附加形式重定向输出和错误输出
< 重定向输入
<< Here语法
<<< Here字符串
grep da * 2>errors.txt 写到
less < errors.txt 读入
/dev/null
comman > /dev/null 2>&1
Debug
在脚本开始加选项
#!/bin/bash options
-f 禁止文件名展开
-i 让脚本以交互模式运行
-n 读取命令 不执行 用于检查
-t 执行第一条命令后退出
-v 执行每条语句钱向stderr输出该命令
-x 执行每条命令钱 向stderr输出该命令及命令的扩展参数