欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

马哥 16_01 _bash脚本编程之十四 信号捕捉及系统管理之任务计划 有大用

image.pngimage.png

定制引导盘 (这个没看懂)

mount 

        -n:挂载时不更新/etc/mtab文件   (默认挂载时是更新的)

cat /proc/mounts




cross compile 交叉编译


x86(指的是cpu),32bit,

在 ARM(指的是cpu)  不能运行

如何实现部分编译

1,只编译某子目录下的相关代码

make dir/

make arch/

make drivers/net/

2,只编译部分模块

make M=drivers/net/   (M表示module吧)

3,只编译某一模块

make drivers/net/pcnet32.ko

4,将编译完成的结果放置于别的目录中

make O=/tmp/kernel  (O 表示output吧)

image.png

5,交叉编译

    make ARCH=          (比如ARM)



image.png

脚本编程知识点

1,变量中字符的长度:${#VARNAME}


2,变量赋值等:

${parameter:-word}:如果parameter为空或未定义,则变量展开为"word";否则展开为parameter的值

${parameter:+word}:如果parameter为空或未定义,不做任何操作;否则展开为"word"的值

${parameter:=word}:如果parameter为空或未定义,则变量展开为"word";并将展开后的值赋值给parameter

${parameter:offset}:取子串,从offset开始,到结束

${parameter:offset:length }:取子串,从offset处的后一个字符开始,取length长的子串

当然有?的,(如果为空的话,就显示错误信息)不常用,


3,脚本配置文件

/etc/rc.d/init.d/服务脚本

服务脚本支持配置文件  /etc/sysconfig/服务脚本同名的配置文件        (通常是这样的)


4,局部变量

local VAR_NAME=



a=1


test() {

  a=$[3+4]

}

test

for I in `seq $a 10`;do

    echo $I

done


5,命令 mktemp        (make temporary file)

创建临时文件或目录

临时文件一般在 /tmp 或 /var/tmp目录下

(/tmp目录下,即使没有删文件,它们也会被定期清理的)

(每隔30天做清理,30天内如果没有被访问,都会被清理掉)


(假如创建的文件有同名, mktemp能解决问题  )

mktemp /tmp/file.XX

mktemp /tmp/file.XXXXX

    -d: 创建为目录


6,信号 

    进程间通信的一种方式,一个进程向另一个进程发送的短小的信息,

能够实现控制另外一个进程的运作法则(运作机制的)

    kill -SIGAL PID       (kill -信号 其它进程的PID)

            信号前面都要加上SIG

            信号 1: HUB  SIGHUP

            信号 2: INT  (interrupt) SIGINT

            信号 9: KILL  SIGKILL

            信号 15:  TERM (terminal) SIGTERM

            

 kill [-s signal_name] pid ...例 kill -s HUB  31265

     kill -l [exit_status]            

     kill -signal_name pid ...        例 kill -HUB  31265

     kill -signal_number pid ...    例 kill -15 31265


脚本中,能实现信号捕捉的,但是 9 和 15 信号捕捉不了


    ctrl + c 2信号,interrupt, SIGINT      中断当前进程


trap 命令 (诱骗 设陷阱 ,捕捉) 捕捉信号的

是 bash的内建命令,可以实现信号捕捉

    trap 'COMMAND'  信号列表


7,一行中执行多个语句,语句间用 ; (分号)分隔即可


任务计划:

1),在未来的某个时间点执行一次某任务

        at 

        batch   (不需要指定时间的,它也执行一次,它会自动选择系统空闲的时候执行这个任务,其它使用格式与at相同)

                at 时间        (未来的时间点,过去的时间点是没有意义的)

                at> COMMOND  (执行命令) (敲回车)

                at> COMMOND  (执行命令) (敲回车)

                at > ctrl +d  (表示提交计划任务)

             这样就会在某个时间点执行了

                指定时间的方法

                   绝对时间 10:20      HH::MM    DD.MM.YY MM/DD/YY

                   相对时间 now+3m (表示3分钟以后执行)(好像3m不行,只能用3minutes)

                        now+#单位  (#井号表示数字)

                                单位有: minutes,hours,days,weeks

                    模糊时间 noon(正午,中行12:00),midnight(午夜,夜里12点),teatime(喝茶时间,下午4点) (pm表示下午,am表示上午)

                

at 8:10 (不一定是今天的8:10,它指的是将来的最近的8:10)


命令的执行结果,将以邮件的形式发送给安排任务计划的用户


at -l  = atq    显示作业 (-l 相当于list吧)

at -d AT_JOB_ID =  atrm AT_JOB_ID                (-d 相当于delete吧)    (AT_JOB_ID  作业号)


可以定义让谁用at,不让谁用at

/etc/at.deny

/etc/at.allow


2),周期性的执行某任务

        cron: 自身是一个不间断运行的服务  (时间点跳过去了,比如某个时间点关机了,这个时间点的任务就不会执行了)(它是运行在长时间不会关机的一个服务器上的)

(cron 本身没有开机时检查该执行而未执行的任务)

        anacron: (cron的补充,能够实现让cron因为各种原因在过去的时间该执行而未执行的任务在恢复正常后执行一次) (只要我们的服务器24小时运行,就不需要anacron)  anacron本身也是必须随时在线执行的(这里的anacron在线指的是笔记本开机后启动起来就行了)

 (只要我们的服务器24小时运行,就不需要anacron,所以服务器默认anacron是不启动的,只有在笔记本上需要经常开机 关机,才需要启动anacron) 


(spool 线轴,线管 ;缠绕)


        cron:  crontab

            系统cron (跟用户没关系,比如每天检查tmp目录,删除未访问的30天前的文件,每天执行updatedb)    /etc/crontab 中

                    7个端 五个端时间,一个端用户,一个端命令

            分钟     小时     天     月      周(星期)    用户     任务

            用户cron

                                /var/spool/cron/USERNAME    (USERNAME    用户名)

                    6个端 五个端时间,一个端命令

            分钟     小时     天     月      周(星期)    任务

            

            时间的有效取值:

            分钟: 0-59

            小时: 0-23

            天: 1-31

            月: 1-12

            分钟: 0-59

            周: 0-7             (0和7都表示周日)


            时间的通配表示:

                *:星号对应的时间的所有有效取值          (3 * ***)(每小时的第3分钟,不是每三分钟,这是一小时一次)         (3 * **7)(每个星期天的每小时的第3分钟,不是每三分钟,这是一小时一次)  (*/2 * * * *)(每隔2分钟执行一次)  (13 12 * * *)(每天的12点13分钟执行一次)(13 12 * * 5)(每周五的12点13分钟执行一次)(13 12 6 * *)(每月6号的12点13分钟执行一次)(13 12 6 * 3)(每月6号并且这一天是星期三的12点13分钟执行一次,这种机会很小的,所以日和星期最好不要同时使用)(13 12 6 7 *)(每年的7月6号的12点13分钟执行一次)

                ,:逗号,离散时间点          (10,40 * ***)   (每小时的第10分钟和第40分,都执行一次,每小时执行了两次)         (10,40 * **2,5)   (每周二,和每周五,的每小时的第10分钟和第40分,都执行一次)     (10,40 2 **2,5)   (每周二,和每周五,的2点的第10分钟和第40分,都执行一次)  (小时什么的 2 和 02是同一个意思,都表示2点,分钟等同理)

                 -:中短横线,连续时间点        (10 02 * * 1-5) (每周一至每周五的2点10分执行一次)

                 /#:除号,对应取值范围内每隔多长时间执行一次( # 井号是数字,表示每隔,频率)        (*/3 * ***)(每3分钟执行一次任务)



(每隔的时候,比它小的时间点一定要给个具体的值)

每两小时执行一次

01 */2 * * * 

每2天执行一次

10 04  */2 * *  


也是(与 at  一样) 执行结果将以邮件形式发送给管理员?应该是用户,不一定管理员吧?

        */3 * * * * cat /etc/fstab &> /dev/null   (不发送给管理员的话 使用重定向 &>表示正确的 和 错误的都送到黑洞  > 表示把正确的送到黑洞)


    cron的环境变量: cron执行的所有命令都去PATH环境变量指定的路径下去找

(如果用户没有登录的话,cron到哪里去找环境变量呢)

       一般来说cron 的  PATH     /bin:/sbin:/usr/bin:/usr/sbin

       如果这里写的命令放在其它位置,以用户的身份能够正常执行,未必以cron能执行

         所以上面的 cat 应该改为 绝对路径 /bin/cat

         如果cron执行的是脚本,脚本里面各种命令,使用绝对路径,很麻烦,可以在脚本当中定义PATH变量就可以了

#!/bin/bash

export PATH=                这样写脚本的时候,就会使用脚本自身的PATH环境变量,而不再使用用户的环境变量了


 用户任务(用户cron任务)的管理:

    crontab

        -l  : (list)列出当前用户的所有cron任务

        -e :编辑 (edit)

        -r :  (remove)移除crontab文件,移除所有任务 (移除一个任务的话就 -e 然后删了这一行就可以了)

        -u USERNAME (上面的选项-l 列出-e 编辑 -r 删除一起用) 管理员可以(使用-u)管理其它用户的cron任务  



    anacron: 只是cron的补充,替代不了cron

               


[root@localhost ~]# read -p "Your file:" FILE

Your file:

[root@localhost ~]# echo $FILE


[root@localhost ~]#


read  有个 -t 超时时间,超过时间之后会自动跳过,并且变量依然为空


[root@localhost ~]# stty -F /dev/console size

25 80

[root@localhost ~]#

如果某个变量没有值,给它个默认值


[root@localhost ~]# A=3

[root@localhost ~]# echo ${A:-30}

3

[root@localhost ~]# unset A        (unset  回收撤销变量)

[root@localhost ~]# echo ${A:-30}

30

[root@localhost ~]# echo $A        (因为已经unset 所以A的值为空)


[root@localhost ~]#

[root@localhost ~]# A=${A:-30}

[root@localhost ~]# echo $A

30

[root@localhost ~]#

[root@localhost ~]# unset A

[root@localhost ~]# echo ${A:-30}

30

[root@localhost ~]# echo ${A:+30}


[root@localhost ~]#


[root@localhost ~]# echo ${A:=30}

30

[root@localhost ~]# echo $A

30

[root@localhost ~]#

[root@localhost ~]# ${B:=30}        (它不能独立正常的运行,所以它不常用)

-bash: 30: command not found

[root@localhost ~]# B=${B:-30}    (用了赋值,可以独立正常的运行)

[root@localhost ~]#

[root@localhost ~]# A='hello word'

[root@localhost ~]# echo ${A:2:3}        

(偏移或跳过2个,取3个)(或者把位置看成是从第0个开始, 就是从第二个开始,取3个)

llo

[root@localhost ~]#


[root@localhost ~]# echo ${A:2}    (长度可以省略)

llo word

[root@localhost ~]#



[root@localhost ~]# vim a.sh

#!/bin/bash

#


[ -n $TEST ] && echo $TEST



[root@localhost ~]# chmod +x a.sh

[root@localhost ~]# ./a.sh


[root@localhost ~]#

[root@localhost ~]# vim a.conf

TEST='hello world'


[root@localhost ~]# vim a.sh

#!/bin/bash

#

. /root/a.conf

[ -n $TEST ] && echo $TEST


[root@localhost ~]# ./a.sh

./a.sh: line 4: [: hello: binary operator expected

[root@localhost ~]# bash -x a.sh

+ . /root/a.conf

++ TEST='hello world'

+ '[' -n hello world ']'

a.sh: line 4: [: hello: binary operator expected

[root@localhost ~]#


[root@localhost ~]# vim ./a.sh     (变量判断要加上引号)

#!/bin/bash

#

. /root/a.conf

[ -n "$TEST" ] && echo $TEST


[root@localhost ~]# ./a.sh

hello world

[root@localhost ~]#



[root@localhost ~]# vim ./a.sh

#!/bin/bash

#

. /root/a.conf

TEST=${TEST:-info}

[ -n "$TEST" ] && echo $TEST



[root@localhost ~]# vim a.conf

TEST=

~



[root@localhost ~]# ./a.sh

info

[root@localhost ~]#


[root@localhost ~]# vim b.sh

#!/bin/bash

#

a=1

test() {

  a=$[3+4]

}

test

for I in `seq $a 10`;do

    echo $I

done

~

[root@localhost ~]# vim b.sh

[root@localhost ~]# chmod +x b.sh

[root@localhost ~]# ./b.sh

7

8

9

10

[root@localhost ~]#


本地变量 环境变量 位置变量 特殊变量 局部变量


[root@localhost ~]# vim b.sh  (加上local 关键字,只在局部范围内有效)

#!/bin/bash

#

a=1

test() {

  local a=$[3+4]

}

test

for I in `seq $a 10`;do

    echo $I

done


[root@localhost ~]# ./b.sh

1

2

3

4

5

6

7

8

9

10

[root@localhost ~]#


[root@localhost ~]# mktemp /tmp/file.XXX    (每次创建的文件名不一样)

/tmp/file.266

[root@localhost ~]# mktemp /tmp/file.XX

/tmp/file.67

[root@localhost ~]# mktemp /tmp/file.XX

/tmp/file.68

[root@localhost ~]# mktemp /tmp/file.XX

/tmp/file.69

[root@localhost ~]#


[root@localhost ~]# mktemp /tmp/file.XXXXX

/tmp/file.x1328

[root@localhost ~]# mktemp /tmp/file.XXXXX

/tmp/file.d1329

[root@localhost ~]# mktemp /tmp/file.XXXXX

/tmp/file.L1331

[root@localhost ~]# mktemp /tmp/file.XXXXX

/tmp/file.B1335

[root@localhost ~]#

mktemp  命令的返回值就是文件路径,我们只要把这个路径保存在变量中即可

[root@localhost ~]# FILE=`mktemp /tmp/file.XXXXX`

[root@localhost ~]# echo $FILE

/tmp/file.Y1568

[root@localhost ~]# echo $FILE

/tmp/file.Y1568

[root@localhost ~]#

[root@localhost ~]#




[root@localhost ~]# mktemp -d /tmp/file.XXXXX         (-d directory 选项,创建临时目录)

/tmp/file.I1745

[root@localhost ~]# ls /tmp

busybox   file.68     file.d1329  file.x1328  vmware-config0    vmware-root

file.266  file.69     file.I1745  file.xx     VMwareDnD

file.67   file.B1335  file.L1331  file.Y1568  vmware-file-mod0

[root@localhost ~]#

[root@localhost ~]# vim showdate.sh

#!/bin/bash

#

while :; do

  date

  sleep 2

done

~


[root@localhost ~]# chmod +x showdate.sh

[root@localhost ~]# ./showdate.sh

2018年 11月 28日 星期三 20:43:11 CST

2018年 11月 28日 星期三 20:43:13 CST


[root@localhost ~]# vim showdate.sh

(用 INT 或 SIGINT都可以吧 表示中断信号)

#!/bin/bash

#

trap 'echo "You go..."' INT        

while :; do

  date

  sleep 2

done



[root@localhost ~]# !vi

vim showdate.sh

[root@localhost ~]# ./showdate.sh  

  ( 按ctrl + c 就是这样的结果 ,ctrl + c  是中断的意思,INT (SIGINT) )

2018年 11月 28日 星期三 20:46:19 CST

2018年 11月 28日 星期三 20:46:21 CST

You go...

2018年 11月 28日 星期三 20:46:21 CST

You go...

2018年 11月 28日 星期三 20:46:22 CST



[root@localhost ~]# kill -l

 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL

 5) SIGTRAP      6) SIGABRT      7) SIGBUS       8) SIGFPE

 9) SIGKILL     10) SIGUSR1     11) SIGSEGV     12) SIGUSR2

13) SIGPIPE     14) SIGALRM     15) SIGTERM     16) SIGSTKFLT

17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP

21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU

25) SIGXFSZ     26) SIGVTALRM   27) SIGPROF     28) SIGWINCH

29) SIGIO       30) SIGPWR      31) SIGSYS      34) SIGRTMIN

35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3  38) SIGRTMIN+4

39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8

43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12

47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14

51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10

55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7  58) SIGRTMAX-6

59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2

63) SIGRTMAX-1  64) SIGRTMAX

[root@localhost ~]#


19 SIGSTOP (Ctrl + z 把已经在前台的正在前台的作业送到后台去,并且停止运行)

18 SIGCONT  (signal continue, bg命令让后台停止的程序在后台继续执行)

后面的太多信号是用户自己自定义的



 kill %JOBID   杀死作业号为JOBID的作业,此时 百分号不能省,假如省了,程序会把JOBID当作进程号


image.png

ctrl +z 停止此进程 并送到后台去

image.png

杀死这个后台的作业号 

[root@localhost ~]# kill %2

[root@localhost ~]#




[root@localhost ~]# vim ping.sh

#!/bin/bash

#

NET=192.168.0

for I in {2..254}; do

  if ping -c 1 -W 1 $NET.$I &> /dev/null; then

      echo "$NET.$I is up."

  else

       echo "$NET.$I is down"

  fi

done


[root@localhost ~]# chmod +x ping.sh



image.png

为什么  ctrl + c 终止不了,因为 ctrl + c 被 ping 命令捕捉到了,

默认被ping命令接收,而不是被脚本bash接收

所以 ctrl + c  只是当前的ping命令不执行而已 

怎样实现脚本能捕捉信号,而且能让它停下来



[root@localhost ~]# vim ping.sh

#!/bin/bash

#

NET=192.168.0

trap 'echo "quit."' INT

for I in {2..254}; do

  if ping -c 1 -W 1 $NET.$I &> /dev/null; then

      echo "$NET.$I is up."

  else

       echo "$NET.$I is down"

  fi

done



[root@localhost ~]# ./ping.sh        (ctrl + c 起作用了)

image.png




[root@localhost ~]# vim ping.sh  

#!/bin/bash

#

NET=192.168.0

trap 'echo "quit.";exit 1' INT

for I in {2..254}; do

  if ping -c 1 -W 1 $NET.$I &> /dev/null; then

      echo "$NET.$I is up."

  else

       echo "$NET.$I is down"

  fi

done


[root@localhost ~]# ./ping.sh          (ctrl + c  此时可以退出了)

192.168.0.2 is down

192.168.0.3 is down

192.168.0.4 is down

quit.

[root@localhost ~]#

[root@localhost ~]# vim ping.sh

#!/bin/bash

#

NET=192.168.0

clearup() {

  echo "quit..."

  exit 1

}

trap 'clearup' INT

for I in {2..254}; do

  if ping -c 1 -W 1 $NET.$I &> /dev/null; then

      echo "$NET.$I is up."

  else

       echo "$NET.$I is down"

  fi

done


[root@localhost ~]# ./ping.sh

192.168.0.2 is down

192.168.0.3 is down

quit...

[root@localhost ~]#

[root@localhost ~]# vim ping.sh

#!/bin/bash

#

NET=192.168.0

FILE=`mktemp /tmp/file.XXXXXX`

clearup() {

  echo "quit..."

  exit 1

}

trap 'clearup' INT

for I in {2..254}; do

  if ping -c 1 -W 1 $NET.$I &> /dev/null; then

      echo "$NET.$I is up." | tee >> $FILE

  else

       echo "$NET.$I is down"

  fi

done



[root@localhost ~]# vim ping.sh    (clearup清理工作)

(tee  file命令既输出到屏幕,又输出到文件)

(tee >  file命令不输出到屏幕,只输出到文件) (相当于把标准输出重定向到文件,所以不输出到标准输出,即不输出到屏幕)

(tee >>  file命令不输出到屏幕,只输出到文件) (相当于把标准输出重定向到文件,所以不输出到标准输出,即不输出到屏幕)


#!/bin/bash

#

NET=192.168.0

FILE=`mktemp /tmp/file.XXXXXX`

clearup() {

  echo "quit..."

  rm -f $FILE

  exit 1

}

trap 'clearup' INT

for I in {2..254}; do

  if ping -c 1 -W 1 $NET.$I &> /dev/null; then

      echo "$NET.$I is up." | tee >> $FILE

  else

       echo "$NET.$I is down"

  fi

done



[root@localhost ~]# rm -Rf /tmp/file.*

[root@localhost ~]# ls

aa.sh            a.sh            busybox-1.20.2.tar.bz2  ping.sh

aa.txt           boot.gz         index.html              showdate.sh

a.conf           b.sh            install.log             sysroot.gz

anaconda-ks.cfg  busybox-1.20.2  install.log.syslog


[root@localhost ~]# ./ping.sh

image.png


重开一个窗口  看到 file开头的临时文件

[root@localhost ~]# ls /tmp

busybox  file.U26067  vmware-config0  VMwareDnD  vmware-file-mod0  vmware-root


[root@localhost ~]# tail -f /tmp/file.U26067

image.png

image.png

(ctrl +c 退出后 临时文件就没有了)

[root@localhost ~]# ls /tmp

image.png



[root@localhost ~]# man at

image.png



[root@localhost linux]# at 05:12 03.12.2018   在年月日时分建一个任务

at> ls -la

at> <EOT>

job 7 at 2018-12-03 05:12

[root@localhost linux]# 




[root@localhost ~]# at now+3

syntax error. Last token seen: 3

Garbled time

[root@localhost ~]# at now+3minutes    (从提交任务( ctrl + d )开始之后三分钟)

at> ls /var

at> cat /etc/fstab

at> <EOT>

job 1 at 2018-12-01 22:10


产生了一个作业

[root@localhost ~]# date

2018年 12月 01日 星期六 22:10:14 CST

[root@localhost ~]# date

2018年 12月 01日 星期六 22:10:14 CST

[root@localhost ~]# date

2018年 12月 01日 星期六 22:10:39 CST

[root@localhost ~]# at now+10minutes

at> cat /etc/issue

at> <EOT>

job 2 at 2018-12-01 22:22

You have new mail in /var/spool/mail/root

[root@localhost ~]# date

2018年 12月 01日 星期六 22:12:20 CST

[root@localhost ~]# at now+3minutes

at> ls /var

at> cat /etc/fstab

at> <EOT>

job 3 at 2018-12-01 22:16

[root@localhost ~]# date

2018年 12月 01日 星期六 22:13:52 CST

[root@localhost ~]# at now+3minutes

at> ls /var/

at> cat /etc/fstab

at> <EOT>

job 4 at 2018-12-01 22:17

[root@localhost ~]# date

2018年 12月 01日 星期六 22:14:46 CST

[root@localhost ~]#


[root@localhost ~]# at -l        (查看作业列表) (相当于 atq)

3       2018-12-01 22:16 a root

2       2018-12-01 22:22 a root

4       2018-12-01 22:17 a root

(第几个作业 作业将要执行的时间 a表示队列,就是分组的意思  root表示是谁的作业)

(队列只能是单个字符,默认是a)

[root@localhost ~]#

[root@localhost ~]# man at

image.png


[root@localhost ~]# at now+10minutes

at> ls /var

at> ls /

at> <EOT>

job 5 at 2018-12-01 22:35

[root@localhost ~]# date

2018年 12月 01日 星期六 22:26:03 CST

[root@localhost ~]# at -l

5       2018-12-01 22:35 a root

[root@localhost ~]# at -d 5  (-d delete删除的意思 就是atrm 的别名 )(删除作业号为5的任务)

[root@localhost ~]#


[root@localhost ~]# at -l        (删除了作业后 就没有了)

[root@localhost ~]#


[root@localhost ~]# mail

Mail version 8.1 6/6/93.  Type ? for help.

"/var/spool/mail/root": 7 messages 7 new

>N  1 logwatch@localhost.l  Thu Nov 22 21:09  43/1647  "Logwatch for localhos"

 N  2 logwatch@localhost.l  Fri Nov 23 20:29 252/7869  "Logwatch for localhos"

 N  3 logwatch@localhost.l  Sat Nov 24 21:49  97/3174  "Logwatch for localhos"

 N  4 root@localhost.local  Sat Dec  1 22:10  44/1310  "Output from your job "

 N  5 root@localhost.local  Sat Dec  1 22:16  44/1310  "Output from your job "

 N  6 root@localhost.local  Sat Dec  1 22:17  44/1310  "Output from your job "

 N  7 root@localhost.local  Sat Dec  1 22:22  17/738   "Output from your job "

&  (此时按q,再按回车键退出) (按数字表示查看第几个邮件(查看的时候也可以按q退出当前邮件))



[root@localhost ~]# service sendmail restart        (重启邮件服务器)

关闭 sm-client:                                           [确定]

关闭 sendmail:                                            [确定]

启动 sendmail:                                            [确定]

启动 sm-client:                                           [确定]


[root@localhost ~]# mail  (可以看到邮件了)

image.png


[root@localhost ~]# man at

/etc/at.allow 白名单

/etc/at.deny 黑名单

如果这两个文件都存在 则只有白名单生效 只允许白名单中的用户执行at任务

如果两个文件都不存在,则只有root用户才能使用at任务 

只用/etc/at.deny  存在,但是为空,表示所有人都允许执行at任务

只用/etc/at.allow   存在,但是为空,表示所有人都不允许执行at任务(当然除了管理员)


[root@localhost ~]# man at

image.png



(/etc/crontab 里面直接定义PATH环境变量了,

系统cron跟用户没关系,可以直接定义它的PATH)

[root@localhost ~]# vim /etc/crontab

SHELL=/bin/bash

PATH=/sbin:/bin:/usr/sbin:/usr/bin

MAILTO=root

HOME=/


# run-parts

01 * * * * root run-parts /etc/cron.hourly        ( run-parts 表示把这个目录/etc/cron.hourly里面的脚本或命令在这个时间点执行一下) (run-parts 是红帽提供给我们的脚本,它能够实现运行/etc/cron.hourly目录下面的每一个脚本或命令)(当然得有权限)

02 4 * * * root run-parts /etc/cron.daily

22 4 * * 0 root run-parts /etc/cron.weekly

42 4 1 * * root run-parts /etc/cron.monthly

image.png


[root@localhost ~]# ls /etc/cron.daily/

00webalizer  0logwatch  cups       makewhatis.cron  prelink  rpm

0anacron     certwatch  logrotate  mlocate.cron     rhsmd    tmpwatch


logrotate 是有关日志的  (rotate是旋转的意思

image.png

(假如同时执行的话,系统非常繁忙)这些命令是有次序的,是按名称来排序的 执行一个后 再执行下一个,这就是run-parts的意义 (想让某个先执行的话 把名称前面加个0等等)


我们想编辑系统cron 直接 vim /etc/crontab 文件


下面是用户cron

[root@localhost ~]# cd /var/spool/cron

[root@localhost cron]# vim root        (编辑或创建用户名的文件就可以了,但是不建议这么做,万一语法有问题,应该就不会执行了,它不会检查语法是否错误)(这里没有执行,ctrl +c 未执行这个命令)

(因此有个命令crontab 来定义cron任务的)


[root@localhost cron]# crontab -l

no crontab for root

[root@localhost cron]# crontab -e        (它里面的命令每执行一次会发送邮件给用户)

no crontab for root - using an empty one  (这是系统提示的字)

*/3 * * * * /bin/echo "how are ya?"


保存后 

[root@localhost cron]# crontab -e

no crontab for root - using an empty one

crontab: installing new crontab


[root@localhost cron]# crontab -e   

*/3 * * * * /bin/echo "how are ya?"

*/5 * * *  /bin/echo "how are ya?"


如果写错了,它会报错,并问你要不要重新编辑 (如果自己在 /var/spool/cron 下面自己写的话它就不会检查错误了)

image.png


最后修正为

[root@localhost cron]# crontab -e

*/3 * * * * /bin/echo "how are ya?"


crontab -e 之后 可以看到/var/spool/cron/下面的名为root (root是用户名)的文件

[root@localhost cron]# ls -la /var/spool/cron/

总计 24

drwx------  2 root root 4096 12-02 15:44 .

drwxr-xr-x 14 root root 4096 11-22 19:30 ..

-rw-------  1 root root   36 12-02 15:44 root

You have new mail in /var/spool/mail/root

[root@localhost cron]#


[root@localhost cron]# crontab -r

You have new mail in /var/spool/mail/root


移除后就看不到了

[root@localhost cron]# crontab -l

no crontab for root


移除后就看不到了

[root@localhost cron]# ls -la /var/spool/cron/

总计 16

drwx------  2 root root 4096 12-02 15:48 .

drwxr-xr-x 14 root root 4096 11-22 19:30 ..

[root@localhost cron]#



[root@localhost cron]# id hadoop

id: hadoop:无此用户

[root@localhost cron]# useradd hadoop

[root@localhost cron]#


[root@localhost cron]# crontab -u hadoop -e

no crontab for hadoop - using an empty one

*/3 * * * * /bin/echo "How are ya?"


可以看到 /var/spool/cron/ 目录下创建了一个叫 hadoop 的文件

[root@localhost cron]# ls /var/spool/cron/

hadoop

[root@localhost cron]#


切换到hadoop 此时可以看到hadoop用户下有任务

[root@localhost cron]# su - hadoop

[hadoop@localhost ~]$ crontab -l

*/3 * * * * /bin/echo "How are ya?"

[hadoop@localhost ~]$


[root@localhost cron]# cat /etc/anacrontab             (anacrontab)

# /etc/anacrontab: configuration file for anacron


# See anacron(8) and anacrontab(5) for details.


SHELL=/bin/sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin

MAILTO=root


1       65      cron.daily              run-parts /etc/cron.daily

7       70      cron.weekly             run-parts /etc/cron.weekly

30      75      cron.monthly            run-parts /etc/cron.monthly

时间(1)       时间(65)     纯注释信息(cron.daily,可以理解为id)    要执行的任务(run-parts /etc/cron.daily)


1:表示过去有1天没执行(每天任务,每分钟任务,小于1天的任务,应该执行1次的,但是1天没有执行了) (最小操作单位是天,过去5分钟跳过执行的cron,它是管不了的,而cron是分)

65:表示开机以后的第65分钟,开始执行



image.png


cron 要能够执行 ,必须确保 crond 服务是启动的

[root@localhost cron]# service crond status

crond (pid  4590) 正在运行...


anacron 要能够执行 ,必须确保 anacron 服务是启动的

[root@localhost cron]# service anacron status

anacron 已停

[root@localhost cron]#


查看安装的服务 chkconfig --list

[root@localhost cron]# chkconfig --list crond

crond           0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭

[root@localhost cron]#


image.png


linux kill 用法示例

kill 是 Linux 系统中用于向进程发送信号的命令。最常用的信号是 TERM(终止信号),它的编号是 15。默认情况下,kill 命令会发送 TERM 信号。

以下是 kill 命令的一些基本用法示例:

1. 发送终止信号

bash复制代码

kill [进程ID]

例如,假设你想终止进程 ID 为 1234 的进程,你可以这样做:  默认信号是 15 

bash复制代码

kill 1234

2. 发送特定信号

你可以使用 -s 选项来指定要发送的信号。例如,要发送 KILL 信号(其编号是 9,该信号会强制终止进程),你可以这样做:

bash复制代码

kill -s KILL 1234

或者,你也可以使用信号的编号来发送信号:

bash复制代码

kill -9 1234

3. 批量发送信号

你可以通过一次调用 kill 命令来发送信号给多个进程。只需在命令行上列出它们的进程 ID,用空格分隔:

bash复制代码

kill 1234 5678 9012

4. 发送信号给属于同一用户的所有进程

你可以使用 -u 选项来发送信号给属于同一用户的所有进程:

bash复制代码

kill -u username

这里的 username 应该替换为实际的用户名。

5. 发送信号给属于同一组的所有进程

使用 -g 选项可以发送信号给属于同一进程组的所有进程:

bash复制代码

kill -g 进程组ID

6. 查找并发送信号

你可以结合其他命令(如 pgrep 或 pidof)来查找进程 ID 并发送给它们。例如,要找到名为 "nginx" 的所有进程并发送 TERM 信号给它们,你可以:

bash复制代码

kill $(pgrep nginx)

或者

bash复制代码

killall nginx

killall 命令会根据进程名来发送信号,而 pkill 命令允许你使用部分进程名进行匹配。

请注意,KILL 信号(-9 或 SIGKILL)是强制性的,它会无视进程是否愿意终止。因此,在使用 KILL 信号之前,最好先尝试使用 TERM 信号(默认或 -15)来优雅地终止进程。如果进程没有响应 TERM 信号,再考虑使用 KILL 信号。



kill [-s signal_name] pid  与 kill -signal_name pid 区别 示例

kill [-s signal_name] pid 和 kill -signal_name pid 在功能上确实是等价的,它们都是用于向指定的进程(由进程ID pid 标识)发送一个特定的信号。这两种形式的主要区别在于是否明确使用了 -s 选项来指示后面的参数是一个信号名称。

下面我将给出这两种形式的示例,并解释它们之间的细微差别:

示例 1:使用 -s 选项明确指定信号名称

bash复制代码

kill -s SIGTERM 1234

在这个示例中,-s 选项后面跟的是信号名称 SIGTERM,它告诉 kill 命令要发送一个终止信号给进程 ID 为 1234 的进程。这种方式非常清晰,对于不熟悉信号编号的用户来说,通过信号名称更容易理解和记忆。

示例 2:直接使用信号名称(省略 -s 选项)

bash复制代码

kill -SIGTERM 1234

在这个示例中,我们直接使用了信号名称 SIGTERM 而没有指定 -s 选项。kill 命令同样会理解这是要发送一个终止信号给进程 ID 为 1234 的进程。这种方式在命令行上可能更简洁一些,但对于不熟悉 kill 命令的用户来说,可能会稍微有些不太直观。

区别总结

  1. 清晰性:使用 -s 选项明确指定信号名称可以使命令更加清晰易懂,特别是对于初学者或那些不熟悉信号编号的用户。

  2. 简洁性:省略 -s 选项可以使命令更简洁,减少输入量,但这可能稍微牺牲了一些清晰性。

  3. 避免混淆:在大多数情况下,信号名称不会与 kill 命令的其他选项或参数冲突,因此省略 -s 选项通常不会导致问题。然而,在极少数情况下,如果信号名称恰好与 kill 命令的某个选项或参数相同,那么省略 -s 选项可能会导致命令解析错误。在这种情况下,使用 -s 选项来明确指定信号名称是更好的选择。

总的来说,这两种形式在功能上是等效的,选择哪一种主要取决于个人偏好和具体场景。为了确保命令的清晰性和避免潜在的混淆,特别是对于那些不熟悉 kill 命令的用户来说,使用 kill [-s signal_name] pid 这种明确指定信号名称的形式可能是一个更好的选择。


普通分类: