#!/bin/bash
#### echo
a="world"
echo hello world ## 输出 hello world
echo 'hello world' ## 输出 hello world
echo "hello world" ## 输出 hello world
echo "hello "${a} ## 输出 hello world
echo "hello ${a}" ## 输出 hello world
echo 'hello ${a}' ## 输出 hello ${a}
echo "1\t2\t3" ## 输出 1\t2\t3
echo -e "1\t2\t3" ## 输出 1 2 3 ## 包含转义字符的字符串
a=`echo "hello ${a}"`;echo $a ## 输出 hello world ## 反撇号将命令执行的结果输出给变量
:<<!
补充:
\a 警告字符,通常为ASCII的BEL字符
\b 后退
\f 换页(formfeed)
\n 换行
\r 回车(Carriage return)
\t 水平制表符
\v 垂直制表符
\\ 一个字面上的反斜杠字符
!
#### printf
printf "%s %d\n" "hello world" 2018
:<<!
输出:
hello world 2018
!
#### 算数运算
a=10;b=20;let c=$a+$b;echo $c ## 输出30
let a++;let c--;echo $a $b $c ## 输出 11 20 29
c=$[a+b];echo $c ## 输出 31
d=$((a+c));echo $d ## 输出 42
c=$(expr $a + $b);echo $c ## 输出 31 注意:用空格隔开每个项
e=$(expr 12 % 5);echo $e ## 输出 2
e=$(expr 3 \* 5);echo $e ## 输出 15
e=$(expr 20 / 6);echo $e ## 输出 3
a=$(echo "4*3.1" | bc);echo $a ## 输出 12.4 注意 expr 只能对整数进行计算,使用bc计算小数
a=$(echo "scale=2;20/6" | bc);echo $a ## 输出 3.33 控制小数位数
a=$(echo "obase=2;2*2" | bc);echo $a ## 输出 100 用二进制进行输出
a=$(echo "scale=3;sqrt(10)" | bc);echo $a ## 输出 3.162
#### 环境变量
export -p ## 输出所有环境变量
export A="a/b/c" ## 定义环境变量A并赋值为a/b/c ## export的作用范围仅作用为当次登陆
unset A ## 清除环境变量
:<<!
环境变量配置文件
全局配置文件:/etc/profile
用户配置文件:~/.bash_profile
!
#### 预定义变量
:<<!
$# ## 命令行中位置参数的个数
$* ## 所有位置参数的内容
$@ ## 所有位置参数的内容
$? ## 上一条命令执行后返回的状态,当返回状态值为0时表示执行正常,非0表示执行异常或出错
$$ ## 当前所在进程的进程号
$! ## 后台运行的最后一个进程号
$0 ## 当前执行的进程/程序名
!
#### 获取标准输入
:<<!
read -p "Please enter something : " -t 10 a;echo "your input : "$a ## -p 显示提示
read -p "Please enter password : " -s a;echo -e "\nyour password : "$a ## -s 不显示输入内容
!
#### 文件描述符和重定向
:<<!
0:标准输入stdin
1:标准输出stdout
2:标准错误输出stderr
>:重定向保存到文件
>>:以追加模式重定向保存到文件
cat a > out 2>&1 ## 将标准输出重定向到文件out,将标准错误输出重定向到标准输出
cat a &> out ## 将标准输出和标准错误输出都重定向到文件out
tee ## 将标准输入重定向以后还可以作为后续命令的标准输入
!
#### 数组
array_pt=( 1 2 3 4 5 6 )
echo ${array_pt[3]} ## 输出4
echo ${array_pt[@]} ## 输出1 2 3 4 5 6
echo ${array_pt[*]} ## 输出1 2 3 4 5 6
echo ${#array_pt[@]} ## 输出6
echo ${#array_pt[*]} ## 输出6
unset array_pt[3];echo ${array_pt[*]} ## 输出1 2 3 5 6
unset array_pt;echo ${array_pt[*]} ## 输出为空
array_pt=( 1 2 3 4 5 6 )
echo ${array_pt[*]:0:4} ##输出1 2 3 4
echo ${array_pt[*]:3:5} ##输出4 5 6
echo ${array_pt[*]:1} ##输出2 3 4 5 6
echo ${array_pt[*]:0} ##输出1 2 3 4 5 6
#### 遍历数组
a=( 1 2 3 4 5 )
for ((i=0;i<${#a[@]};i++)) ## 方法1
do
echo ${a[i]}
done
declare -A array_var ## 声明关联数组,bash 4.0以上版本支持
array_var=( [one]=one-1 [two]=two-2 [three]=three-3 [four]=four-4 [five]=five-5 [six]=six-6 )
echo ${!array_var[*]} ##取出索引
for index in ${!array_var[*]} ## 关联数组的遍历
do
echo ${array_var[$index]}
done
#### alias 命令
:<<!
alias a='echo "hello world"'
使用alias时,用户必须使用单引号''将原来的命令引起来,防止特殊字符导致错误。
alias命令的作用只局限于该次登入的操作。若要每次登入都能够使用这些命令别名,则可将相应的alias命令存放到bash的初始化文件/etc/bashrc中。
unalias a ## 删除别名
!
#### 函数的定义
function add1()
{
local a=$1
local b=$2
echo $a $b
return $((a+b))
}
add1 1 2;echo $? ## 输出3,这里函数中用return返回值,在函数外用$?接收函数返回值
add2()
{
echo $(($1+$2))
}
c=`add2 3 4`;echo $c ## 输出7,这里函数里用echo 返回值,在函数外用`add2 3 4`接收返回值
#### 文件条件表达式
:<<!
格式
[ 操作符 文件或目录 ]
操作符:
-d:测试是否为目录,是则为真(Directory)
-e:测试目录或文件是否存在,存在则为真(Exist)
-f:测试是否为文件,是则为真(file)
-r:测试当前用户是否有权限读取,是则为真(read)
-w:测试当前用户是否有权限写入,是这为真(write)
-x:测试当前用户是否可执行该文件,可执行则为真(Excute)
-L:测试是否为符号链接文件,是则为真(Link)
-nt:file1 -nt file2 如果 file1 比 file2 新(修改时间),则为真
-ot:file1 -ot file2 如果 file1 比 file2 旧(修改时间),则为真
!
mkdir a
if [ -d a ];
then
echo "a is a folder"
rm -r a
else
echo "a is a file"
fi
#### 字符串条件表达式
:<<!
格式
[ 字符串1 = 字符串2 ]
[ 字符串1 != 字符串2 ]
[ -z 字符串 ]
操作符:
=:字符串内容相同则为真,就是说包含的文本一摸一样。
!=:字符串内容不同,则为真(!号表示相反的意思)
-z:字符串内容为空(长度为零)则为真
-n:字符串内容非空(长度非零)则为真
<:string1 < string2 如果string1在本地的字典序列中排在string2之前,则为真
>:string2 如果string1在本地的字典序列中排在string2之后,则为真
!
#### 判断参数为空
if [ -z "$conf_dir" ];then
echo 'argv error'
exit
fi
#### 整数值比较
:<<!
格式
[ 整数1 操作符 整数2 ]
-eq:等于(equal)
-ne:不等于(not equal)
-gt:大于(Greater than)
-lt:小于(lesser than)
-le:小于等于(lesser or equal)
-ge:大于等于(Greater or equal)
!
#### 逻辑表达式
:<<!
格式
[ 表达式1 ] 操作符 [ 表达式2 ] ...
操作符
-a 或 && :逻辑与,“而且”的意思,前后两个表达式都成立时整个测试结果才为真,否则为假
-o 或 || : 逻辑或,“或者”的意思,操作符两边至少一个为真时,结果为真,否为为假
! :逻辑否,当制定条件不成立时,返回结果为真
!
#### for循环语句
for var in a b c
do
echo $var
done
:<<!
输出:
a
b
c
!
for i in {1..4}
do
echo $i '循环' ##输出
done
for i in $(seq 2 4)
do
echo $i
done
:<<!
输出:
2
3
4
!
for((i=0;i<3;i++))
do
echo $i
done
:<<!
输出;
0
1
2
!
#### while 循环
i=1
while [ $i -le 4 ] ##注意:方括号前后空格
do
echo $i
let i++
done
i=1
while [ $i -lt 4 ] ## 注意:方括号前后空格
do
if [ $i -eq 2 ];
then
echo "i=2"
let i++
continue
fi
echo $i
i=`expr $i + 1` ## 注意运算符前后空格
done
###########################################################################################
#### date命令
:<<!
选项:
-d<字符串>:显示字符串所指的日期与时间。字符串前后必须加上双引号;
-s<字符串>:根据字符串来设置日期与时间。字符串前后必须加上双引号;
-u:显示GMT;
--help:在线帮助;
--version:显示版本信息。
日期格式:
%H 小时,24小时制(00~23)
%I 小时,12小时制(01~12)
%k 小时,24小时制(0~23)
%l 小时,12小时制(1~12)
%M 分钟(00~59)
%p 显示出AM或PM
%r 显示时间,12小时制(hh:mm:ss %p)
%s 从1970年1月1日00:00:00到目前经历的秒数
%S 显示秒(00~59)
%T 显示时间,24小时制(hh:mm:ss)
%X 显示时间的格式(%H:%M:%S)
%Z 显示时区,日期域(CST)
%a 星期的简称(Sun~Sat)
%A 星期的全称(Sunday~Saturday)
%h,%b 月的简称(Jan~Dec)
%B 月的全称(January~December)
%c 日期和时间(Tue Nov 20 14:12:58 2012)
%d 一个月的第几天(01~31)
%x,%D 日期(mm/dd/yy)
%j 一年的第几天(001~366)
%m 月份(01~12)
%w 一个星期的第几天(0代表星期天)
%W 一年的第几个星期(00~53,星期一为第一天)
%y 年的最后两个数字(1999则是99)
!
date +"%Y-%m-%d %H:%M:%S"
date -d "1 day ago" +"%Y-%m-%d %H:%M:%S"
date +%Y%m%d #显示当前天年月日
date -d "+1 day" +%Y%m%d #显示前一天的日期
date -d "-1 day" +%Y%m%d #显示后一天的日期
date -d "-1 month" +%Y%m%d #显示上一月的日期
date -d "+1 month" +%Y%m%d #显示下一月的日期
date -d "+1 month 20190101" +%Y%m%d #显示指定日期的下一月的日期
date -d "-1 year" +%Y%m%d #显示前一年的日期
date -d "2018 +1 year" +%Y%m%d #显示2018年下一年的日期
start=$(date +"%S")
nmap baidu.com &> /dev/null
end=$(date +"%S")
echo "times="$(($end-$start))
#### 打印范围内的所有日期
MONTH=$1
if [ -z "$MONTH" ];then
echo 'argv error'
exit
fi
LAST_MONTH=$(date -d "${MONTH}01 last month" +%Y%m)
NEXT_MONTH=$(date -d "${MONTH}01 next month" +%Y%m)
START_DAY=${MONTH}01
END_DAY=$( date -d "1 day ago ${NEXT_MONTH}01" +"%Y%m%d")
echo "START_DAY:"${START_DAY} "END_DAY:"${END_DAY}
i=0
while [[ $DAY -lt ${END_DAY} ]];
do
DAY=$(date -d " -${i} day ago ${START_DAY}" +%Y%m%d)
echo ${DAY}
let i++
done
#### sleep命令
b=''
for ((i=0;$i<=100;i++))
do
printf "Progress:[%-100s]%d%%\r" $b $i
sleep 0.01
b=#$b
done
echo
#### find命令
find ~/tmp -name "*.txt" ## 查找目标文件夹以.txt结尾的文件
#### tr命令
## 对来自标准输入的字符进行替换、压缩、删除操作
:<<!
-c或——complerment:取代所有不属于第一字符集的字符;
-d或——delete:删除所有属于第一字符集的字符;
-s或--squeeze-repeats:把连续重复的字符以单独一个字符表示;
-t或--truncate-set1:先删除第一字符集较第二字符集多出的字符。
!
echo "HELLO WORLD" | tr 'A-Z' 'a-z' ## hello world
echo "hello 123 world 456" | tr -d '0-9' ## hello world
echo "thissss is a text linnnnnnne." | tr -s ' sn' ## this is a text line.
#### sort命令
:<<!
-b:忽略每行前面开始出的空格字符;
-c:检查文件是否已经按照顺序排序;
-d:排序时,处理英文字母、数字及空格字符外,忽略其他的字符;
-f:排序时,将小写字母视为大写字母;
-i:排序时,除了040至176之间的ASCII字符外,忽略其他的字符;
-m:将几个排序号的文件进行合并;
-M:将前面3个字母依照月份的缩写进行排序;
-n:依照字符串数值的大小排序;
-g:依照数值的大小排序;
-o<输出文件>:将排序后的结果存入制定的文件;
-r:以相反的顺序来排序;
-t<分隔字符>:指定排序时所用的栏位分隔字符;
+<起始栏位>-<结束栏位>:以指定的栏位来排序,范围由起始栏位到结束栏位的前一栏位。
!
sort -nk 2 -t: sort.txt ## 将以:分割的文件中第二列按照字符串数字顺序进行排序
sort -gk 2 -t: sort.txt ## 将以:分割的文件中第二列按照数字大小进行排序
#### grep 命令
## 格式 :grep pattern files
* : 表示当前目录所有文件,也可以是某个文件名
-r 是递归查找
-n 是显示行号
-R 查找所有文件包含子目录
-i 忽略大小写
例如:grep -rn "hello,world!" * #递归查找当前路径下所有文件中包含hello world!的行
## 批量 kill 进程
#! /bin/bash
searchName=$1
pids=$(ps -ef | grep ${searchName} |grep -v grep |awk '{print $2}')
for pid in ${pids}
do
ps -ef|grep ${pid}
echo "kill pid" ${pid}
done
echo 'finished ...'