第07天 [Shell脚本编程基础]

要想运行的脚本直接写文件名运行,需要把目录加在环境变量中
PATH=.:PATH
全局环境变量
让所有⽤户的PATH“环境变量”的值多出⼀个路径,/usr/local/apache/bin,并让其⽣效?
vim /etc/profile
export PATH=/usr/local/apache/bin:$PATH
source /etc/profile 
进程pid
	echo $BASHPID 查看进程
	echo $PPID 查看上一级进程
	(umansk 066;touch a.txt) 临时性赋值,只在小括号里面有效,对后续没有影响
	[root@Centos7 shelldata]#a=1
	[root@Centos7 shelldata]#(echo $a;a=2;echo $a)
	1
	2
	[root@Centos7 shelldata]#echo $a
	1


scp 脚本 
	scp $1 [email protected]:/data/scripts37 &&echo "上传成功!"

检测脚本中的语法错误
	bash -n /path/to/some_script
 调试执行
	bash -x /path/to/some_script

declare mylove='Visual C++'   #定义新环境变量
set -a mylove                 #设置为环境变量
env | grep mylove             #显示环境变量值

set 设置环境变量,取消用unset
	declare mylove='cvvvc'
	[root@Centos7 shelldata]#set mylove
	[root@Centos7 shelldata]#echo $mylove
	cvvvc



位置参数 
$0 代表命令叫什么名字
$1 代表脚本后面的第一个参数
$2 代表脚本后面的第二个参数,这个地方的参数是按顺序来的,跨顺序不会传递进去,如果参数是$10的
时候记得这样写 ${10}
$* 表示传递的所有参数全部参数合为一个字符串
$@ 表示传递的所有参数每个参数为独立字符串
$# 表示传递参数的总数
---------------------------------------------------
脚本arg.sh
echo "1st arg is $1"
echo "2st arg is $2"
echo "3st arg is $3"
echo "all args are $*"
echo "all args are $@"
echo "arg number is $#"
echo "the scriptname is $0"
[root@Centos7 shelldata]#sh arg.sh ab c d
1st arg is ab
2st arg is c
3st arg is d
all args are ab c d
all args are ab c d
arg number is 3
the scriptname is arg.sh
------------------------------------------------------
脚本scp.sh

scp $* [email protected]:/data/scripts/ && echo "上传成功"



------------------------------------------------------
脚本rm.sh
num1=`tree /rubbish/|wc -l`
num2=2
let sumz=$num1-$num2
mkdirtmp=`date +%F`"_"$sumz
mkdir -p  /rubbish/$mkdirtmp
mv  $* /rubbish/$mkdirtmp/ &&echo "移动成功"


------------------------------------------------------
ping ip
ping -c1 -W1 hostdown &> /dev/null
echo $?
ping c1 ip &>/dev/null
echo $?

bash中的算术运算:help let
+, -, *, /, %取模(取余), **(乘方),乘法符号有些场景中需要转义
实现算术运算:
(1) let var=算术表达式
(2) var=$[算术表达式]
(3) var=$((算术表达式))
(4) var=$(expr arg1 arg2 arg3 ...)
(5) declare –i var = 数值
(6) echo ‘算术表达式’ | bc
?bash有内建的随机数生成器变量:$RANDOM(0-32767)
示例:生成 0 - 49 之间随机数
echo $[$RANDOM%50]



-------------------------------
cmd1 || cmd2;如果cmd1成功,不执行cmd2,如果失败执行
cmd1 && cmd2 ,如果cmd1成功,执行cmd2.


短路运算
短路与   逻辑与
第一个为0,结果必定为0
第一个为1,第二个必须要参与运算
echo $[5&9]
短路或
第一个为1,结果必定为1
第一个为0,第二个必须要参与运算
?异或:^
异或的两个值,相同为假,不同为真


----------------------------------------

sdasum=`df|tr  -s " "|cut -d" " -f5|grep [0-9]|sort -nr|tr -d %|head -1`
echo "最大值"$sdasum
test $sdasum -ge 80 &&echo "warning"||echo "no waning"





bash的数值测试
-v VAR
变量VAR是否设置
数值测试:
-gt  是否大于
-ge  是否大于等于
-eq  是否等于
-ne  是否不等于
-lt  是否小于
-le  是否小于等于
bash的字符串测试

字符串测试:
=  是否等于
>  ascii码是否大于ascii码
<  是否小于
!=  是否不等于
=~  左侧字符串是否能够被右侧的PATTERN所匹配 包含例子  str good;[[$str =~o{2,}]]
注意: 此表达式一般用于[[ ]]中;扩展的正则表达式
-z "STRING“  字符串是否为空,空为真,不空为假
-n "STRING“  字符串是否不空,不空为真,空为假
注意:用于字符串比较时的用到的操作数都应该使用引号
Bash的文件测试

存在性测试
-a FILE:同 -e
-e FILE: 文件存在性测试,存在为真,否则为假
存在性及类别测试
-b FILE:是否存在且为块设备文件
-c FILE:是否存在且为字符设备文件
-d FILE:是否存在且为目录文件
-f FILE:是否存在且为普通文件
-h FILE 或 -L FILE:存在且为符号链接文件
-p FILE:是否存在且为命名管道文件
-S FILE:是否存在且为套接字文件
Bash的文件权限测试

文件权限测试:
-r FILE:是否存在且可读
-w FILE: 是否存在且可写
-x FILE: 是否存在且可执行

文件特殊权限测试:
-u FILE:是否存在且拥有suid权限
-g FILE:是否存在且拥有sgid权限
-k FILE:是否存在且拥有sticky权限
Bash的文件属性测试

文件大小测试:
-s FILE: 是否存在且非空
文件是否打开:
-t fd: fd 文件描述符是否在某终端已经打开
-N FILE:文件自从上一次被读取之后是否被修改过
-O FILE:当前有效用户是否为文件属主
-G FILE:当前有效用户是否为文件属组
Bash的文件属性测试

双目测试:
FILE1 -ef FILE2: FILE1是否是FILE2的硬链接
FILE1 -nt FILE2: FILE1是否新于FILE2(mtime)
FILE1 -ot FILE2: FILE1是否旧于FILE2
Bash的组合测试条件
 第一种方式:
EXPRESSION1 -a EXPRESSION2 并且
EXPRESSION1 -o EXPRESSION2 或者
! EXPRESSION
必须使用测试命令进行,[[ ]] 不支持
? 第二种方式:
COMMAND1 && COMMAND2 并且, 短路与,代表条件性的AND THEN
COMMAND1 || COMMAND2 或者, 短路或,代表条件性的OR ELSE
! COMMAND 非
如:[ -f “$FILE” ] && [[ “$FILE”=~ .*\.sh$ ]]

[ "$A" = "$B" ] && echo "Strings are equal"
例子:str=good; [[ $str =~ o{2,} ]] && echo y || echo no
y 一定要有空格不然执行报错,上面双括号里面有4个空格

条件测试
测试命令:
test EXPRESSION
[ EXPRESSION ]
[[ EXPRESSION ]]
注意:EXPRESSION前后必须有空白字符


使用read来把输入值分配给一个或多个shell变量
-p 指定要显示的提示
-s 静默输入,一般用于密码
-n N 指定输入的字符长度N
-d ‘字符’ 输入结束符
-t N TIMEOUT为N秒
read 从标准输入中读取值,给每个单词分配一个变量
所有剩余单词都被分配给最后一个变量
read -p “Enter a filename: “ FILE
read -s passwd 
echo $passwd   此时输入密码的时候就不会显示在终端



if 条件判断
if 判断条件1; then
条件1为真的分支代码
elif 判断条件2; then
条件2为真的分支代码
elif 判断条件3; then
条件3为真的分支代码
else
以上条件都为假的分支代码
fi



case 变量引用 in
PAT1)
分支1
;;
PAT2)
分支2
;;
...
*)
默认分支
;;
esac

#!/bin/bash

str="is good "
read -p "你喜欢什么颜色:" color

case $color in

	red) echo -e "\e[1;31m$color $str \e[0m";;
    
	green) echo -e "\e[1;32m$color $str \e[0m";;
    
	yellow) echo -e "\e[1;33m$color $str \e[0m";;
    
	blue) echo -e "\e[1;34m$color $str \e[0m";;
    
	*) echo -e "\e[1;30m这是什么颜色?\e[0m";;

esac



-------------------------------------------------------------------------------------
脚本useradd.sh
[ $# -eq 0 ]&& { echo "usage `basename $0`";exit ; }
id $1 &> /dev/null &&  { echo esists ; exit ; } || echo no esists                                                            
useradd $1 &>/dev/null && { echo $1 is created ; echo mageedu |passwd --stdin $1 &> /dev/null ; } || { echo "error" ; exit ; }

---------------------------------------------------------------------------------------
脚本age.sh
read -p "input your age " age
if [[ ! "$age" =~ ^[0-9]+$ ]]; then 
	echo "please again"
	exit
elif [ $age -lt 18 ] ;then 
	echo "xiao18";
elif [ $age -le 60 ] ;then
	echo "xiao60";
elif [ $age -le 120 ] ;then
	echo "xiao120";
else 
	echo "6"
fi

---------------------------------------------------------------------------------------
脚本yesorno.sh    切记赋值=前后
不允许有空格
read -p "please youe answer    " value
value=`echo $value |   tr 'A-Z' 'a-z'`
echo $value
[[ "$value" =~ ^(y|yes)$ ]] && echo you chose yes && exit;
[[ "$value" =~ ^(n|no)$ ]] && echo you chose no || echo chose again ;
---------------------------------------------------------------------------------------

脚本 yorncase.sh
read -p "input yes or no" answer
case $answer in
[Yy]|[Yy][Ee][Ss])
	echo yes
	;;
[Nn]|[Nn][Oo])
	echo no
	;;
*)
	echo chose again
	;;
esac


交互式登录:
(1)直接通过终端输入账号密码登录
(2)使用“su - UserName” 切换的用户
执行顺序:/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile -->
~/.bashrc --> /etc/bashrc
非交互式登录:
(1)su UserName
(2)图形界面下打开的终端
(3)执行脚本
(4)任何其它的bash实例
执行顺序: /etc/profile.d/*.sh --> /etc/bashrc -->~/.bashrc



.bash_logout 文件表示退出时候会执行此文件里面的命令


$- 变量
h:hashall,打开这个选项后,Shell 会将命令所在的路径hash下来,避免每次
都要查询。通过set +h将h选项关闭
i:interactive-comments,包含这个选项说明当前的 shell 是一个交互式的
shell。所谓的交互式shell,在脚本中,i选项是关闭的。
m:monitor,打开监控模式,就可以通过Job control来控制进程的停止、继
续,后台或者前台执行等。
B:braceexpand,大括号扩展
H:history,H选项打开,可以展开历史列表中的命令,可以通过!感叹号来完
成,例如“!!”返回上最近的一个历史命令,“!n”返回第 n 个历史命令


set 命令 一般我们在写脚本的时候建议加 set -u 和 set -e
-u 在扩展一个没有设置的变量时,显示错误信息
等同set –o nounset
-e 如果一个命令返回一个非0退出状态值(失败)就退出
等同set –o errexit


编写脚本/root/bin/sysinfo.sh显示当前主机系统信息,包括主机名,操作系统版本,内核版本,CPU型号,内存大小,硬盘分区。
#!/bin/env bash
# Filename: sysinfo.sh
# Author: Yu Longjun
echo "主机名  : $HOSTNAME"
echo "系统版本: `cat /etc/centos-release`"
echo "内核版本: `uname -r`"
echo "CPU型号 :`cat /proc/cpuinfo | grep "model name"|cut -d: -f2|head -1`"
echo "内存大小: `free -m |grep Mem|tr -s " "|cut -d" " -f2` MB"
echo -e "硬盘分区:\n`df -hT |egrep -o "^/dev/sd.*\>"|tr -s " " | cut -d" " -f1,3|sort`"


写一个shell脚本,实现批量添加20个用户,用户名为user01-20,密码为user后面跟5个随机字符
#!/bin/bash
#description: useradd
for i in seq `1 20`
do
pwd=$(cat /dev/urandom | head -1 | md5sum | head -c 5)
#passwd=`echo $RANDOM | md5sum | cut -c 1-5`
useradd user$i
echo "user$i$pwd" | passwd --stdin user$i
echo user$i user$i$pwd" >> userinfo.txt
done


取前10访问量
cat /app/nginx/logs/access.log |awk -F" " '{print $1}'|uniq -c |sort -nr|head -10

你可能感兴趣的:(Linux知识汇总)