是一个程序,可以解析shell命令
环境变量
本地变量
自定义的变量——局限在某个脚本中使用
1、变量定义:
VAR=hello or VAR=“hello”
注意事项:
2、一些命令实例
将一个命令执行之后的结果赋值给某个变量(下面两种方式都可以)
var=`pwd`
var=$(pwd)
算术运算(只能在整型之间做算数运算)
var=9
var=$((var+10))
var=$[var+10]
用export命令可以把本地变量导出为环境变量
export VARNAME //只在当前终端中有效
export VARNAME=value
位置变量
特殊变量
注意!!!加上“”之后,$*和$@会发生变化!!!
将执行完命令之后得到的数据保存到变量
VAR=`shell命令`
VAR=$(shell命令) -- 常用,推荐使用
1、对变量取值
在变量的前边加 $
$VAR
2、对变量做算术运算
3、进制运算
$[base#n] 数值按照几进制进行运算
\
VAR='$(date)'
单引号中的内容原样输出
VAR="$(date)"
会继续双引号中的命令, 输出结果字符串
下面两种方式皆可
比较 test , [] , [[]]
区别:
例子:
上图中pwd执行成功了,因此返回值是0
linux中的文件种类: 7种
-b filename |
当filename 存在并且是块文件时返回真(返回0) |
-c filename |
当filename 存在并且是字符文件时返回真 |
-d pathname |
当pathname 存在并且是一个目录时返回真 |
-e pathname |
当由pathname 指定的文件或目录存在时返回真 |
-f filename |
当filename 存在并且是正规(普通)文件时返回真 |
-g pathname |
当由pathname 指定的文件或目录存在并且设置了SGID 位时返回真 |
-h/-L filename |
当filename 存在并且是符号链接文件时返回真 (或 filename) |
-k pathname |
当由pathname 指定的文件或目录存在并且设置了"粘滞"位时返回真 |
-p filename |
当filename 存在并且是命名管道时返回真 |
-r pathname |
当由pathname 指定的文件或目录存在并且可读时返回真 |
-s filename |
当filename 存在并且文件大小大于0 时返回真 |
-S filename |
当filename 存在并且是socket 时返回真 |
-t fd |
当fd 是与终端设备相关联的文件描述符时返回真 |
-u pathname |
当由pathname 指定的文件或目录存在并且设置了SUID 位时返回真 |
-w pathname |
当由pathname 指定的文件或目录存在并且可写时返回真 |
-x pathname |
当由pathname 指定的文件或目录存在并且可执行时返回真 |
-O pathname |
当由pathname 存在并且被当前进程的有效用户id 的用户拥有时返回真(字母O 大写) |
-G pathname |
当由pathname 存在并且属于当前进程的有效用户id 的用户的用户组时返回真 |
file1 -nt file2 |
file1 比file2 新时返回真 |
file1 -ot file2 |
file1 比file2 旧时返回真 |
f1 -ef f2 |
files f1 and f2 are hard links to the same file |
例如,测试文件filename是否为目录文件
-z string |
字符串string 为空串(长度为0)时返回真 |
-n string |
字符串string 为非空串时返回真 |
str1 = str2 |
字符串str1 和字符串str2 相等时返回真 |
str1 == str2 |
同 = |
str1 != str2 |
字符串str1 和字符串str2 不相等时返回真 |
nt1 -eq int2 |
如果int1 等于int2,则返回真 |
int1 -ne int2 |
如果int1 不等于int2,则返回真 |
int1 -lt int2 |
如果int1 小于int2,则返回真 |
int1 -le int2 |
如果int1 小于等于int2,则返回真 |
int1 -gt int2 |
如果int1 大于int2,则返回真 |
int1 -ge int2 |
如果int1 大于等于int2,则返回真 |
-a |
逻辑与,操作符两边均为真,结果为真,否则为假。 |
-o |
逻辑或,操作符两边一边为真,结果为真,否则为假。 |
! |
逻辑否,条件为假,结果为真。 |
语法格式
if [ 条件判断语句 ];then
处理语句
处理语句
elif [ 条件判断语句 ]
then
处理语句
处理语句
else
处理语句
处理语句
fi
:——是一个特殊的命令,称为空命令
if :; then
xxxx
fi
基本语法
case 变量 in
yes|Yes|y|Y)
处理语句
处理语句
;;
No|no|n|N)
处理语句
处理语句
;;
*)
处理语句
;;
esac
例子
a.sh
./a.sh aa
VAR=$1
case VAR in
a*|AA|a|A)
echo "a"
;;
b|bb|BB)
echo b
;;
*)
echo "hello"
;;
esac
语法格式
for 变量 in list(列表);do
控制语句
控制语句
done
例子(下面两个for循环的结果相同)
for VAR in $(ls) ;do
echo $VAR
done
for VAR in `ls` ;do
echo $VAR
done
语法格式
while [ 条件测试语句 ];do
控制语句
控制语句
done
例子——输入三次密码,三次错误退出程序
PWD=world
count=1
echo "请输入密码"
read TMP
while [ $TMP != $pwd -a $count le 3 ];do
echo "密码错误,请重新输入"
read TMP
count=$[count+1]
do
break 可以选择跳出的层数
break n
echo 字符串
例子:
cmd > file
cmd >> file
例子——将指令cmd的标准输出(1)重定向到file,标准错误(2)重定向到标准输出(1)——标准输出和标准错误都写入file文件中
cmd > file 2>&1
#等价于
cmd 1 > file 2 > &1
1、awk缺省的行分隔符是换行
2、缺省的列分隔符是连续的空格和Tab
3、如何取出每一列
4、如果不是缺省分隔符的如何指定分隔符
5、例子——拆分/etc/passwd,找到每个用户对应的家目录
awk -F: '{print $6}' /etc/passwd
awk 参数 '/pattern/{actions}' 目标文件
awk 参数 'condition{actions}' 目标文件
awk 参数 脚本文件 目标文件
例子——找出以g开头的字符串的第三列
awk -F/ '/^g/{print $3}' test
awk -v x=10 '条件/正则表达式{action} ' 文件名
第一步——找出所有进程号在1000到2000之间的进程
ps -aux | awk '$2>1000 && $2<2000{print $2}'
第二步,设置变量x(x的默认值为0),用于记录当前符合条件的进程号是第几个符合条件的
ps -aux | awk '$2>1000 && $2<2000{print $2; x=x+1; print x}'
第三步,添加条件END(END——代表遍历结束)
ps -aux | awk '$2>1000 && $2<2000{x=x+1}END{print x}'
#!/bin/bash
# 关闭tracker 和 storage服务
#shell脚本没有返回值,没有参数,但是可以传参
tracker_start()
{
#查找名为fdfs_trackerd的进程; grep -v grep的意思是过滤掉grep进程
#> /dev/null重定向到垃圾回收站,扔进去之后,输出就没有了
ps aux | grep fdfs_trackerd | grep -v grep > /dev/null
#如果查到了该进程,则$?的值是0
if [ $? -eq 0 ];then
echo "fdfs_trackerd 已经在运行中, 无需启动..."
else
#说明该进程没有被启动
sudo fdfs_trackerd /etc/fdfs/tracker.conf
if [ $? -ne 0 ];then
echo "tracker start failed ..."
else
echo "tracker start success ..."
fi
fi
}
storage_start()
{
ps aux | grep fdfs_storaged | grep -v grep > /dev/null
if [ $? -eq 0 ];then
echo "fdfs_storaged 已经在运行中, 无需启动..."
else
sudo fdfs_storaged /etc/fdfs/storage.conf
if [ $? -ne 0 ];then
echo "storage start failed ..."
else
echo "storage start success ..."
fi
fi
}
#如果没传入参数
if [ $# -eq 0 ];then
echo "Operation:"
echo " start storage please input argument: storage"
echo " start tracker please input argument: tracker"
echo " start storage && tracker please input argument: all"
echo " stop storage && tracker input argument: stop"
exit 0
fi
case $1 in
storage)
storage_start
;;
tracker)
#调用shell函数tracker_start
tracker_start
;;
all)
storage_start
tracker_start
;;
stop)
sudo fdfs_trackerd /etc/fdfs/tracker.conf stop
sudo fdfs_storaged /etc/fdfs/storage.conf stop
;;
*)
echo "nothing ......"
esac
1、 grep -v grep ——过滤掉grep
2、> /dev/null——将输出扔掉
#!/bin/bash
#定义变量
START=1
STOP=1
case $1 in
start)
START=1
STOP=0
;;
stop)
START=0
STOP=1
;;
"")
STOP=1
START=1
;;
*)
STOP=0
START=0
;;
esac
# **************************** 杀死正在运行的CGI进程 ****************************
if [ "$STOP" -eq 1 ];then
# 登录
kill -9 $(ps aux | grep "./bin_cgi/login" | grep -v grep | awk '{print $2}') > /dev/null 2>&1
echo "CGI 程序已经成功关闭, bye-bye ..."
fi
# ******************************* 重新启动CGI进程 *******************************
if [ "$START" -eq 1 ];then
# 登录 -n代表不加换行
echo -n "登录:"
spawn-fcgi -a 127.0.0.1 -p 10000 -f ./bin_cgi/login
echo "CGI 程序已经成功启动 ^_^..."
fi
1、> /dev/null 2>&1——将标准输出和标准错误全都扔掉
2、 echo -n ——不加换行
#!/bin/bash
NAME=redis
FILE=redis.pid
# 判断redis目录是否存在, 如果不存在则创建
is_directory()
{
#如果传入的第一个参数不是目录
if [ ! -d $1 ]; then
echo "$1 目录创建中..."
mkdir $1
if [ $? -ne 0 ];then
echo "$1 目录创建失败, ~~~~(>_<)~~~~"
exit 1
fi
fi
}
# 判断redis目录是否存在, 如果不存在则创建
is_regfile()
{
if [ ! -f $1 ]; then
#statements
echo "$1 file not exist..."
return 1
fi
return 0
}
# 根据参数设置redis状态
#提示用户需要传入参数
if [[ $1 = "" ]];then
echo "please input argument:"
echo " start: start redis server"
echo " stop: stop redis server"
echo " status: show the redis server status"
exit 1
fi
# 函数调用,函数传入的参数是$NAME
is_directory $NAME
case $1 in
start)
# 判断 redis-server 进程是否已经启动...
ps aux | grep "redis-server" | grep -v grep > /dev/null
if [ $? -eq 0 ];then
echo "Redis server is runing ..."
else
# 删除$FILE 文件
unlink "$NAME/$FILE"
echo "Redis starting ..."
redis-server ./conf/redis.conf
if [ $? -eq 0 ];then
echo "Redis server start success!!!"
# 休眠1s, 等待pid文件被创建出来, 再进行后续判断
sleep 1
if is_regfile "$NAME/$FILE";then
# printf是一个命令,用于在中断进行输出
printf "****** Redis server PID: [ %s ] ******\n" $(cat "$NAME/$FILE")
printf "****** Redis server PORT: [ %s ] ******\n" $(awk '/^port /{print $2}' "./conf/redis.conf")
fi
fi
fi
;;
stop)
# 判断 redis-server 进程是否已经启动...
ps aux | grep "redis-server" | grep -v grep > /dev/null
if [ $? -ne 0 ];then
echo "Redis server is not runing..."
exit 1
fi
echo "Redis stopping ..."
# 判断pid文件是否存在
#调用函数is_regfile,传入的参数罗列在函数调用的后面,即$NAME/$FILE
if is_regfile "$NAME/$FILE"; then
# 读进程文件
echo "### 通过 redis.pid文件 方式关闭进程 ###"
PID=$(cat "$NAME/$FILE")
else
# 查找进程ID
echo "### 通过 查找进程ID 方式关闭进程 ###"
PID=$(ps aux | grep "redis-server" | grep -v grep | awk '{print $2}')
fi
echo Redis server pid = $PID
kill -9 $PID
if [ $? -ne 0 ]; then
echo "Redis server stop fail ..."
else
echo "Redis server stop success!!!"
fi
;;
status)
ps aux | grep "redis-server" | grep -v grep > /dev/null
if [ $? -eq 0 ];then
echo "Redis server is running..."
else
echo "Redis server is not running ..."
fi
;;
*)
echo "do nothing ..."
;;
esac