Shell——基础命令

一、crontab配置(定时)

1、功能

在固定的间隔时间执行指定的系统指令或 shell script脚本。时间间隔的单位可以是分钟、小时、日、月、周及以上的任意组合。这个命令非常适合周期性的日志分析或数据备份等工作。

2、安装

[root@node03 ~]# yum install crontabs
已加载插件:fastestmirror, security
设置安装进程
Loading mirror speeds from cached hostfile
 * base: mirrors.tuna.tsinghua.edu.cn
 * extras: mirrors.163.com
 * updates: mirrors.tuna.tsinghua.edu.cn
base                                                            | 3.7 kB     00:00     
extras                                                          | 3.4 kB     00:00     
updates                                                         | 3.4 kB     00:00     
包 crontabs-1.10-33.el6.noarch 已安装并且是最新版本
无须任何处理

service crond start  			## 启动服务
service crond stop  			## 关闭服务
service crond restart			## 重启服务
service crond reload  			## 重新载入配置
service crond status			## 查看crontab服务状态
service crond start				## 手动启动crontab服务
chkconfig --list				## 查看crontab服务是否已设置为开机启动
chkconfig  --level 35 crond on	## 加入开机自动启动

3、修改任务计划命令

crontab [-u user] file
crontab [-u user] [ -e | -l | -r ]

(1)说明:

-u user ##用来设定某个用户的crontab服务,例如,“-u ixdba”表示设定ixdba用户的crontab服务,此参数一般有root用户来运行。
file 	##file是命令文件的名字,表示将file做为crontab的任务列表文件并载入crontab。
-e 		##编辑某个用户的crontab文件内容。如果不指定用户,则表示编辑当前用户的crontab文件。
-l 		##显示某个用户的crontab文件内容,如果不指定用户,则表示显示当前用户的crontab文件内容。
-r 		##删除定时任务配置,从/var/spool/cron目录中删除某个用户的crontab文件,如果不指定用户,则默认删除当前用户的crontab文件。
-i 		##在删除用户的crontab文件时给确认提示。

(2)命令示例:

crontab file [-u user]		## 用指定的文件替代目前的crontab。 

crontab -l [-u user]		## 列出用户目前的crontab. (重)
crontab -e [-u user]		## 编辑用户目前的crontab. (重)

##例:
 crontab -e
 */1 * * * * echo “haha” >> /root/haha.txt
 */1 * * * * echo “xixi” >> /root/xixi.txt

##编辑的这个文件在/var/spool/cron

crontab -r 					##删除定时任务

4、调度配置

(1)配置说明

基本格式 : 
  *  *  *  *  *  command 
##分  时  日  月  周  命令 
##第1列表示分钟1~59 每分钟用*或者 */1表示 
##第2列表示小时0~23(0表示0点) 7-9表示:7点到9点之间
##第3列表示日期1~31 
##第4列表示月份1~12 
##第5列标识号星期0~6(0表示星期天) 
##第6列要运行的命令 

(2)配置示例

##每分钟执行一次date命令
*/1 * * * * date >> /root/date.txt
##每晚的21:30重启apache
30 21 * * * /usr/local/etc/rc.d/httpd restart 
 ##每月1、10、22日的4 : 45重启apache
45 4 1,10,22 * * /usr/local/etc/rc.d/httpd restart 
##每周六、周日的1 : 10重启apache
10 1 * * 6,0 /usr/local/etc/rc.d/httpd restart 
##每天18 : 00至23 : 00之间每隔30分钟重启apache
0,30 18-23 * * * /usr/local/etc/rc.d/httpd restart 
##每星期六的11 : 00 pm重启apache
0 23 * * 6 /usr/local/etc/rc.d/httpd restart 
##每一小时重启apache
* */1 * * * /usr/local/etc/rc.d/httpd restart 
##晚上11点到早上7点之间,每隔一小时重启apache
* 23-7/1 * * * /usr/local/etc/rc.d/httpd restart 
##每月的4号与每周一到周三的11点重启apache 
0 11 4 * mon-wed /usr/local/etc/rc.d/httpd restart 
##一月一号的4点重启apache 
0 4 1 jan * /usr/local/etc/rc.d/httpd restart 

二、shell编程

Shell是用户与内核进行交互操作的一种接口,目前最流行的Shell称为bash Shell
Shell也是一门编程语言<解释型的编程语言>,即shell脚本<就是在用linux的shell命令编程>
一个系统可以存在多个shell,可以通过cat /etc/shells命令查看系统中安装的shell,不同的shell可能支持的命令语法是不相同的

1、基本格式

代码写在普通文本文件中,通常以 .sh为后缀名

[root@node03 shelllx]# vi hello.sh
##下面在文件中进行,后面不做赘述 以Tab代表
	##按一下a、i、o中任意一个进入编辑模式
	#!/bin/bash    ## 表示用哪一种shell解析器来解析执行我们的这个脚本程序
	echo "hello world"  ##注释也可以写这里
	##Esc退出编辑模式
	##Shift+zz或:wq保存或退出   :q!退出且不保存
##执行脚本
[root@node03 shelllx]# sh hello.sh
hello world
##直接执行脚本
[root@node03 shelllx]# ./hello.sh
-bash: ./hello.sh: 权限不够
##给脚本添加权限
[root@node03 shelllx]# chmod 755 hello.sh 
[root@node03 shelllx]# ./hello.sh
hello world

2、基本语法

(1)系统变量
Linux Shell中的变量分为“系统变量”和“用户自定义变量”,可以通过set命令查看变量

[root@node03 shelllx]# set
BASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:expand_aliases:extquote:force_fignore:hostcomplete:interactive_comments:login_shell:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="4" [1]="1" [2]="2" [3]="2" [4]="release" [5]="x86_64-redhat-linux-gnu")
BASH_VERSION='4.1.2(2)-release'
COLORS=/etc/DIR_COLORS
COLUMNS=87
CVS_RSH=ssh
DIRSTACK=()
DISPLAY=localhost:11.0
EUID=0
......

系统变量: H O M E 、 HOME、 HOMEPWD、 S H E L L 、 SHELL、 SHELLUSER等

[root@node03 shelllx]# a=1
_=
a=1
colors=/etc/DIR_COLORS

##打印变量的值
[root@node03 shelllx]# echo $a
1

[root@node03 shelllx]# a=hello world
-bash: world: command not found
##多了一个空格,world命令不存在
[root@node03 shelllx]# a="hello world"
[root@node03 shelllx]# echo $a
hello world

##在变量a的输出hello world后边+s
[root@node03 shelllx]# echo $a+"s"
hello world+s

[root@node03 shelllx]# echo $as

##前两种均无法正确输出
[root@node03 shelllx]# echo $a"s"
hello worlds

[root@node03 shelllx]# echo ${a}s
hello worlds

(2)自定义变量
1)
变量=值 (例:STR=abc)
等号两侧不能有空格
变量名称一般习惯为大写
使用变量: $arg

双引号和单引号有区别,双引号仅将空格脱意,单引号会将变量引用比如$param脱意

[root@node03 shelllx]# STR="hello world"
[root@node03 shelllx]# A=9
[root@node03 shelllx]# echo $A
9
[root@node03 shelllx]# echo $STR
hello world
##打印hello worlds is greate
[root@node03 shelllx]# echo $STRs is greate
is greate
##上述方法显然不对,应该用以下方法
[root@node03 shelllx]# echo ${STR}s is greate
hello worlds is greate

##撤销变量
[root@node03 shelllx]# unset A
[root@node03 shelllx]# echo $A


##声明静态变量
[root@node03 ~]# readonly g=2
[root@node03 ~]# echo $g
2
[root@node03 ~]# g=3   #不能更改
-bash: g: readonly variable

export 		把变量提升为当前shell进程中的全局环境变量,可供其他子shell程序使用
##不做export定义
[root@node03 shelllx]# vi a.sh
	:!/bin/bash
	a="a in a.sh"
	echo $a
	/home/shelllx/b.sh
[root@node03 shelllx]# vi b.sh
	#!/bin/bash
	b="b in b.sh"
	echo $b
	echo $a
[root@node03 shelllx]# chmod 755 a.sh
[root@node03 shelllx]# chmod 755 b.sh
[root@node03 shelllx]# sh a.sh
a in a.sh
b in b.sh
##未在b脚本打出定义的a变量

##做export定义
root@node03 shelllx]# vi a.sh
	:!/bin/bash
	export a="a in a.sh"
	echo $a
	/home/shelllx/b.sh
[root@node03 shelllx]# vi b.sh  ##子进程
	#!/bin/bash
	b="b in b.sh"
	echo $b
	echo $a
[root@node03 shelllx]# chmod 755 a.sh
[root@node03 shelllx]# chmod 755 b.sh
[root@node03 shelllx]# sh a.sh
a in a.sh
b in b.sh
a in a.sh
##a变量成了a.sh脚本所在bash进程的全局变量,该进程的所有子进程都能访问到变量a

总结:
1、a.sh中直接调用b.sh,会让b.sh在a所在的bash进程的“子进程”空间中执行
2、而子进程空间只能访问父进程中用export定义的变量
3、一个shell进程无法将自己定义的变量提升到父进程空间中去
4、“.”号执行f脚本时,会让脚本在调用者所在的shell进程空间中执行
2)反引号赋值

[root@node03 shelllx]# A=`ls -la`
[root@node03 shelllx]# echo $A
总用量 32 drwxr-xr-x 2 root root 4096 9月 2 20:46 . drwxr-xr-x. 8 root root 4096 9月 2 18:00 .. -rwxr-xr-x 1 root root 42 9月 2 20:45 a.sh -rwxr-xr-x 1 root root 42 9月 2 19:32 b.sh -rwxr-xr-x 1 root root 169 8月 27 13:53 cheng.sh -rwxr-xr-x 1 root root 52 8月 27 11:29 dashuju.sh -rw-r--r-- 1 root root 96 8月 27 11:39 dashuju.txt -rwxr-xr-x 1 root root 141 9月 2 18:51 hello.sh

[root@node03 shelllx]# A=$(ls -la)
[root@node03 shelllx]# echo $A
总用量 32 drwxr-xr-x 2 root root 4096 9月 2 20:46 . drwxr-xr-x. 8 root root 4096 9月 2 18:00 .. -rwxr-xr-x 1 root root 42 9月 2 20:45 a.sh -rwxr-xr-x 1 root root 42 9月 2 19:32 b.sh -rwxr-xr-x 1 root root 169 8月 27 13:53 cheng.sh -rwxr-xr-x 1 root root 52 8月 27 11:29 dashuju.sh -rw-r--r-- 1 root root 96 8月 27 11:39 dashuju.txt -rwxr-xr-x 1 root root 141 9月 2 18:51 hello.sh

3)特殊变量

$? 			##上一个命令退出的状态码(0-255)
$$  		##当前进程编号
$0  		##当前脚本名称
$n  		##n位置的输入参数(n代表数字,n>=1)
$# 			##表示参数的个数,常用于循环
$*$@  	##表示参数列表 

##注:$*与$@区别
##相同点
	##都表示传递给函数或脚本的所有参数
	##都以$1  $2  … $n 的形式组成参数列表
##不同点
	##"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式组成一个整串;
	##"$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式组成一个参数列表

##演示
[root@node03 shelllx]# vi canshu.sh
	#!/bin/basg
	echo $$
	echo $?
	echo $1
	echo $2
	echo $3
	echo $4
	echo $*
	echo $@
	echo $#
	echo $0
[root@node03 shelllx]# sh canshu.sh b c m s f
2870
0
b
c
m
s
b c m s f
b c m s f
5
canshu.sh

3、算数表达式运算

(1)expr
expr m + n 或$((m+n))

##分布计算
[root@node03 shelllx]# S=`expr 2 + 3`
[root@node03 shelllx]# B=`expr $S \* 4`     ## *需要转义
[root@node03 shelllx]# echo $B
20

##一步完成
[root@node03 shelllx]# expr `expr 2 + 3 ` \* 4
20
[root@node03 shelllx]# echo `expr \`expr 2 + 3\` \* 4`
20

(2)(())

[root@node03 shelllx]# a=$((1+2))    ##一定要加$
[root@node03 shelllx]# echo $a    
3

(3)$[]

[root@node03 shelllx]# a=$[1+2]
[root@node03 shelllx]# echo $a
3

(4)let

[root@node03 shelllx]# i=1
[root@node03 shelllx]# let i++
[root@node03 shelllx]# echo $i
2

4、流程控制

(1)if语法
1)

##结果
if condition 
then 
    statements 
[elif condition 
    then statements. ..] 
[else 
    statements ] 
fi

##示例
[root@node03 shelllx]# vi hello.sh 
	#!/bin/bash    
	read -p "please input your name:" NAME   ##从控制台读取输入数据     
	if [ $NAME = root ]
        then
            echo "hello ${NAME},  welcome !"
    elif [ $NAME = ydhl2 ]
        then
            echo "hello ${NAME},  welcome !"
    else
        echo "Get out here !"
fi
[root@node03 shelllx]# sh hello.sh 
please input your name:ydhl2     
hello ydhl2,  welcome !
[root@node03 shelllx]# sh hello.sh 
please input your name:xxx
Get out here !

##错误
[root@node03 shelllx]# vi hello.sh 
	#!/bin/bash    
	read -p "please input your name:" NAME   ##从控制台读取输入数据     
	if [ $NAME=root ]
        then
            echo "hello ${NAME},  welcome !"
    elif [ $NAME = ydhl2 ]
        then
            echo "hello ${NAME},  welcome !"
    else
        echo "Get out here !"
fi
[root@node03 shelllx]# sh hello.sh 
please input your name:xxx
hello xxx,  welcome !
##错误原因:if [ $NAME=root ]中=两边没有空格,默认$NAME=root是输入一个参数,条件永远成立

2)判断条件
①基本语法

[root@node03 shelllx]# if [ a = b ];then echo ok;else echo notok;fi
notok

[root@node03 shelllx]# if [ a=b ];then echo ok;else echo notok;fi
ok
##不加空格默认只有一个参数,[]非空则返回true

[root@node03 shelllx]# if [ a = a ];then echo ok;else echo notok;fi
ok

②短路(三元运算符)

##满足条件执行&&后面的语句,不满足执行||后面的语句
[root@node03 shelllx]# a=2
[root@node03 shelllx]# b=2
[root@node03 shelllx]# c=3
[root@node03 shelllx]# [ $a = $b ] && echo ok || echo notok
ok
[root@node03 shelllx]# [ $a = $c ] && echo ok || echo notok
notok

③条件判断组合
注:[] 与[[ ]] 的区别:[[ ]] 中逻辑组合可以使用 &&、|| 符号,而[] 里面逻辑组合可以用 -a(and)、-o(or)

[root@node03 shelllx]# if [ a = b && b = c ]; then echo ok;else echo notok;fi
-bash: [: missing `]'
notok
[root@node03 shelllx]# if [ a = b -a b = b ]; then echo ok;else echo notok;fi
notok
[root@node03 shelllx]# if [ a = b -o b = b ]; then echo ok;else echo notok;fi
ok
[root@node03 shelllx]# if [[ a = b && b = b ]]; then echo ok;else echo notok;fi
notok
[root@node03 shelllx]# if [[ a = b || b = b ]]; then echo ok;else echo notok;fi
ok

④判断运算符

##字符串比较
=    	##字符串是否相等
!=   	##字符串是否不相等   
-z 		##字符串长度为0返回true
-n 		##字符串长度不为0返回true
##示例
if [ 'aa' = 'bb' ]; then echo ok; else echo notok;fi
if [ -n "aa" ]; then echo ok; else echo notok;fi
if [ -z "" ]; then echo ok; else echo notok;fi

##整数比较
-lt 	##小于
-le 	##小于等于
-eq 	##等于
-gt 	##大于
-ge 	##大于等于
-ne 	##不等于
\<      ##转义的数学符号   

##文件判断:
if [ -d /bin ]; then echo ok; else echo notok;fi		##-d 是否为目录
if [ -f /bin/ls ]; then echo ok; else echo notok;fi		##-f 是否为文件 
if [ -e /bin/ls ]; then echo ok; else echo notok;fi		##-e 是否存在

(2)while语法

##第一种
while expression
do
commanddone

##第二种
i=1
while ((i<=3))
do
  echo $i
  let i++
done

##示例
[root@node03 shelllx]# vi while.sh
[root@node03 shelllx]# sh while.sh 
1
2
3

(3)case语法(常用)

[root@node03 shelllx]# vi case.sh
	case $1 in
	start)
		echo "starting"
		;;
	stop)
		echo "stoping"
		;;
	*)
		echo "Usage: {start|stop}"
	esac
[root@node03 shelllx]# sh case.sh 2
Usage: {start|stop}
[root@node03 shelllx]# sh case.sh start
starting
[root@node03 shelllx]# sh case.sh stop
stoping

(4)for语法
①方式一

##第一种
[root@node03 shelllx]# vi for.sh
	for N in 1 2 a
	do
        echo $N
	done
[root@node03 shelllx]# sh for.sh
1
2
a

##第二种
[root@node03 shelllx]# for N in 1 2 3; do echo $N; done
1
2
3

##第三种
[root@node03 shelllx]# for N in {1..3}; do echo $N; done
1
2
3

②方式二

##第一种
[root@node03 shelllx]# vi for.sh
	for ((i = 0; i <= 5; i++))
	do
        echo "welcome $i times"
	done
[root@node03 shelllx]# sh for.sh
welcome 0 times
welcome 1 times
welcome 2 times
welcome 3 times
welcome 4 times
welcome 5 times

##第二种
[root@node03 shelllx]# for ((i = 0; i <= 5; i++)); do echo "welcome $i times"; done
welcome 0 times
welcome 1 times
welcome 2 times
welcome 3 times
welcome 4 times
welcome 5 times

③练习:打印九九乘法表

[root@node03 shelllx]# vi cheng.sh
	echo ""
	echo "9x9乘法表"
	echo ""
	for ((i = 1; i <= 9; i++))
	do
        for ((j = 1; j <= i; j++))
        do
             echo -n "$i x $j = $[ $i * $j ]"$'\t'
        done
             echo ""
             echo ""
	done
[root@node03 shelllx]# sh cheng.sh

9x9乘法表

1 x 1 = 1	

2 x 1 = 2	2 x 2 = 4	

3 x 1 = 3	3 x 2 = 6	3 x 3 = 9	

4 x 1 = 4	4 x 2 = 8	4 x 3 = 12	4 x 4 = 16	

5 x 1 = 5	5 x 2 = 10	5 x 3 = 15	5 x 4 = 20	5 x 5 = 25	

6 x 1 = 6	6 x 2 = 12	6 x 3 = 18	6 x 4 = 24	6 x 5 = 30	6 x 6 = 36	

7 x 1 = 7	7 x 2 = 14	7 x 3 = 21	7 x 4 = 28	7 x 5 = 35	7 x 6 = 42	7 x 7 = 49	

8 x 1 = 8	8 x 2 = 16	8 x 3 = 24	8 x 4 = 32	8 x 5 = 40	8 x 6 = 48	8 x 7 = 56	8 x 8 = 64	

9 x 1 = 9	9 x 2 = 18	9 x 3 = 27	9 x 4 = 36	9 x 5 = 45	9 x 6 = 54	9 x 7 = 63	9 x 8 = 72	9 x 9 = 81	

5、函数使用

(1)函数定义

[root@node03 shelllx]# vi func1.sh
	hello()    ## 函数定义
	{
        echo "Hello there today's date is `date +%Y-%m-%d`"
        return  2      ###返回值是状态码,只能在[0-255]范围内
	}  
	echo "now going to the function hello"
	hello
	echo $?  #获取函数的return值(即:返回上一条命令执行的后的值。true返回0,false返回1)  
	echo "back from the function"
[root@node03 shelllx]# vi func1.sh
[root@node03 shelllx]# sh func1.sh 
now going to the function hello
Hello there today's date is 2019-09-03
2
back from the function

##函数调用
function hello()  
function hello
hello

##脚本调试
sh -vx helloWorld.sh
##或者在脚本中增加set -x

注意:
1.必须在调用函数地方之前,先声明函数,shell脚本是逐行运行。不会像其它语言一样先预编译
2.函数返回值,只能通过$? 系统变量获得,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)
(2)参数函数

[root@node03 shelllx]# vi fun1.sh
	funWithParam(){
   		echo "第一个参数为 $1 !"
    	echo "第二个参数为 $2 !"
    	echo "第十个参数为 $10 !"
    	echo "第十个参数为 ${10} !"
    	echo "第十一个参数为 ${11} !"
    	echo "参数总数有 $# 个!"
    	echo "作为一个字符串输出所有参数 $* !"
	}
	funWithParam 1 2 3 4 5 6 7 8 9 34 73
[root@node03 shelllx]# sh fun1.sh
第一个参数为 1 !
第二个参数为 2 !
第十个参数为 10 !
第十个参数为 34 !
第十一个参数为 73 !
参数总数有 11 个!
作为一个字符串输出所有参数 1 2 3 4 5 6 7 8 9 34 73 !

注意: $ 10 不能获取第十个参数,获取第十个参数需要 $ {10}。当n>=10时,需要使用${n}来获取参数
(3)函数返回值

[root@node03 shelllx]# vi fun2.sh
	funWithReturn(){
    	echo "这个函数会对输入的两个数字进行相加运算..."
    	echo "输入第一个数字: "
    	read aNum
    	echo "输入第二个数字: "
    	read anotherNum
    	echo "两个数字分别为 $aNum$anotherNum !"
    	return $(($aNum+$anotherNum))
	}
	funWithReturn
	echo "输入的两个数字之和为 $? !"
[root@node03 shelllx]# sh fun2.sh
这个函数会对输入的两个数字进行相加运算...
输入第一个数字: 
9
输入第二个数字: 
8
两个数字分别为 9 和 8 !
输入的两个数字之和为 17 !

(4)跨脚本调用函数

[root@node03 shelllx]# vi fun_other.sh
		. /home/shelllx/fun2.sh   
		## 注:  . 和 / 之间有空格
		# 或者 source /home/shelllx/fun2.sh
[root@node03 shelllx]# sh fun_other.sh
这个函数会对输入的两个数字进行相加运算...
输入第一个数字: 
6
输入第二个数字: 
4
两个数字分别为 6 和 4 !
输入的两个数字之和为 10 !

6、except的使用

痛点:使用scp命令远程拷贝文件时,会有人机交互的过程,如何让脚本完成人机交互?
妙药: expect
用法示例:
先观察 ssh localhost 的过程
再看expect的功能

[root@node03 shelllx]# vi exp_test.sh
	set timeout -1;
	spawn ssh localhost;
	expect {
    	"(yes/no)" {send "yes\r";exp_continue;}
    	"password:" {send "hadoop\r";exp_continue;}
    	eof        {exit 0;}
	}
[root@node03 shelllx]# expect -f exp_test.sh
spawn ssh localhost
The authenticity of host 'localhost (::1)' can't be established.
RSA key fingerprint is e0:b8:15:42:b5:88:8b:ac:f2:b3:bd:c1:4f:35:23:d7.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'localhost' (RSA) to the list of known hosts.
Last login: Mon Sep  2 22:49:32 2019 from 192.168.72.1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值