• tee命令,“T型管道”,将STDIN的数据同时发送到两个目的地。一个是STDOUT,另一个是tee命令行指定的文件名:tee filenametee会覆盖原文件,-a参数不会覆盖
  • Linux信号
    信号描述
    1SIGHUP挂起进程
    2SIGINT中断进程
    3SIGQUIT停止进程
    9SIGKILL无条件终止进程
    15SIGTERM如果可能的化终止进程
    17SIGSTOP无条件停止,但不终止进程
    18SIGTSTP停止或暂停进程,但不终止它
    19SIGCONT重新启动停止的进程
  • 默认情况下bash shell会忽略它接收的任何SIGQUIT(3)和SIGTERM(15)信号,以防止交互的shell意外终止。shell会处理它收到的任何SIGHUP(1)和SIGINT(2)信号

    • 中断进程:Ctrl+C,生成SIGINT信号
    • 暂停进程:Ctrl+Z,生成SIGTSTP信号,停止后程序仍然留在内存中(可以ps命令查看)
  • trap命令可以指定能够通过shell脚本监控和拦截的Linux信号。:trap ”commands“ signals(必须用双引号)

  • trap常用的捕获信号:SIGINT SIGHUP EXIT SIGTERM。

  • 移除捕获可以使用破折号作为命令和想要恢复正常行为的信号列表:e.g:trap - EXIT

  • 可以在命令后加上**&**符号使后台模式运行shell脚本。也可同时启动任何数量的相同的后台作业。

  • nohup命令可以使脚本在结束前以后台模式运行:nohup ./shell脚本 & 运行后shell会给该命令分配一个作业编号,Liunx系统分配一个PID编号。使用nohup后台脚本将忽略任何SIGHUP信号。nohup.out文件包含通常发送到终端监视器的所有输出。(如果使用nohup运行另一个命令,输出将添加到现有的nohup.out文件)

  • 脚本使用$$变量显示Linux系统分配给脚本的PID

  • 作业控制:

    • jobs可以查看shell处理的当前作业。
    • jobs命令输出作业可能带有加号和减号。带有加号的作业被视为默认作业。带有减号的作业是待默认作业。只能有一个加号和一个减号的作业。
    • bg 作业号后台程序前台运行。
  • 多任务操作系统中,内核负责为系统中运行的每个进程分配CPU时间。CPU一次只能运行一个进程。默认情况下,从shell启动的所有进程在Linux系统上的调度优先级(scheduling priority)都相同。

  • 调度优先级从-20(最高优先级)到+20(最低优先级),bash shell优先级为0.

  • 调命令优先级:

    • nice -n设置启动命令时的优先级e.g:nice -n 10 ./test >file &nice不允许普通系统用户增加命令的优先级。
    • renice(更改系统中运行的命令优先级,与nice有区别e.g:renice 10 -p 24552:
      • renice命令自动更新运行进程的调度优先级
      • 与nice一样的限制:不允许普通系统用户增加命令的优先级。
  • at命令(给定时间内运行)at -f filename time #-f指定用于读取命令的文件名(脚本文件)

  • at可以识别的时间格式:

    • 标准的小时和分钟格式,比如10:15
    • AM/PM指示符,比如10:15PM
    • 具体指定的时间,比如now、noon、midnight、teatime(4PM)
    • 如果指定一个过去的时间,at命令将在第二天的那个时间运行作业。
    • 标准的日期格式,比如MMDDYY、MM/DD/YY或DD.MM.YY
    • 文本日期格式,比如Jul4或Dec 25,有没有年份都可以
    • 还可以指定时间增量:
      • Now+25minutes
      • 10:15PM tomorrow
      • 10:15+7days
  • 使用at命令时,作业将提交到作业队列(job queue)中,有26种不同的作业队列可用于不同的优先级水平。使用a到z引用作业队列。默认at作业都提交到作业队列a(最高),使用-q参数改变优先级。

  • 作业在Linux系统运行时,没有与该作业关联的监视器。Linux使用提交作业的用户的电子邮件地址作为STDOUT和STDERR。任何以STDOUT和STDERR为目的地的输出都将通过邮件系统发送给用户(mail)

  • atq命令能够查看系统中排队的作业

  • atrm+作业号可以移除排队的作业。

  • batch命令与at命令稍有不同。安排脚本在系统使用率低时运行。batch -f filename time(可以指定batch命令应该尝试运行作业的最早时间)

  • 与at命令类似,默认情况下batch命令从STDIN读取命令。

  • cron:调度需定期运行的作业:corn程序在后台运行,它从特殊表格(cron)中查找需要调度运行的作业。

    • corn使用特殊格式指定作业运行的时间,表格格式:min hour dayofmonth month dayofweek command

      1
      2
      3
      4
      
      15 10 * * * command #每天10:15运行命令
      15 10 * * * 1 command #每周一下午4:15运行
      00 12 1 * * command #每个月第一天的中午12点执行
      00 12 * * * if[ 'date +%d -d tommorow' =01 ];then;command #在每天12点查看本日是否是该月的最后一天,如果是,它将运行命令
      
    • 使用crontab命令构建cron表格,列出现有的cron表格:crontab -l;向cron表格添加条目:crontab -e

    • anacron程序使用时间戳确定调度的作业是是否在正确的时间间隔运行。如果它确定某个作业错过了调度的运行时间,它将自动尽快运行该作业。(该特性对于执行例行日志维护的脚本非常有用。)

    • anacron使用自己的表格(通常:/etc/anacrontab)指定作业。:period delay identiier command period定义总也应该多久运行一次,以天为单位。delay项指定在anacron程序确定应该运行一个命令之后需要多长时间才会实际运行该命令。该选项可以为不同的命令这只不同额延迟值,以防所有命令在一打开Linux系统时运行。identifier项是一个位移的非空字符串,可以唯一地识别日志消息和错误电子邮件中的作业。

  • Linux运行级别

    运行级别描述运行级别描述
    0停止4未使用
    1单用户模式5多用户模式,有网络和图形X Window会话
    2多用户模式,通常没有网络支持5多用户模式,有网络和图形X Window会话
    3完全多用户模式,有网络
  • Linux系统提供了一些脚本文件,用于让脚本在系统启动或者用户启动新的bash shell时运行。rc.local(对于openSusE是boot.local)文件可以列出每次系统启动时启动的脚本。这可以帮助系统管理员在系统启动时运行特定的脚本,以进行系统维护。与此类似.bash_profile和.bashrc文件位于每个用户的主目录,提供一个位置防止与新shell一起运行的脚本和命令。.bash_profile文件在每次用户登陆系统时运行脚本,.basshrc文件按在每个新shell启动时运行脚本。

  • 创建函数

1
2
3
4
5
6
7
8
(1)
function name (
   commands
)
(2)
name(){
   coommands
}
  • shell定义函数时,应将定义在前。

  • shell函数结尾不要使用默认退出状态。可以使用return命令以特定退出状态退出函数。return命令可以使用单个整数值来定义函数退出状态。必须注意避免两个容易发生的错误:

    • 函数完成后尽快提取返回值
    • 退出状态的取值范围是0-255(变量$?提取)
  • 正如命令输出可以捕获并存放到shell变量中一样,函数输入也可捕获并存放到shell变量中:e.g:result='shell函数名'(反引号)这种方法可以返回浮点数和字符串值,所以这种方法能够非常灵活地从函数返回数据。

  • 向函数传递参数:bash shell将函数作为小型脚本处理。

  • 函数使用两种类型的变量:

    • 全局变量(这种方法有风险,尤其对多个shell脚本共用的函数)

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      
      #!/bin/bash
      #demonstrating a bad use of variable
      function func1 {
      temp=$[ $value+5 ]
      result=$[ $temp*2 ]
      }
      temp=4
      value=6
      func1
      echo "The result is $result"
      if [ $temp -gt $value]
      then
          "temp is larger"
      else
          "temp is smaller"
      fi
      
    • 局部变量:local temp

  • 向函数传递数组:先用echo $@将数组整个传入函数中,随后更具命令行参数重建数组变量。:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    
    **实例1:**
    #!/bin/bash
    #carry variable to function test
    function testit {
    local newarray
    newarray=('echo "$@"')
    echo "The new array value is ${newwarray[*]}"
    }
    mayarray=(1 2 3 4 5)
    echo "The original array is ${myarrar[*]}"
    testit ${myarray[*]}
    **实例2:**
    #!/bin/bash
    #adding values in an array
    funcion addarray {
    local sum=0
    local newarray
    newarray=('echo "$@"')
    for value in ${newarray[*]}
    do
        [ $sum+$value ]
    done
    echo $sum
    }
    myarray=(1 2 3 4 5)
    echo "The original array is :${myarray[*]}"
    arg1='echo ${myarray[I]}'
    result='addarray $arg1'
    echo "The result is $result"
    
  • 从函数返回数组:(数组的调用和返回关键在于 echo “$@”

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
    #!/bin/bash
#returning an array value
function arraydblr {
	local origarray
	local newarray
	local elements
	local i
	origarray=(`echo "$@"`)
#	newarray=(`echo "$@"`)
	elements=$[ $# - 1 ]
	for ((i=0;i<=$elements;i++))
	{
		newarray[$i]=$[ ${origarray[$i]}*2 ]
	}
	echo ${newarray[*]}
}
myarray=(1 2 3 4 5)
echo "The orignal array is: ${myarray[*]}"
myarray=`echo ${myarray[*]}` #arg1
result=(`arraydblr $myarray`)
echo "The new array is :${result[*]}"
  • 函数递归
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
    #!/bin/bash
#using recursion
factorial() {
	if [ $1 -eq 1 ]
	then 
		echo 1
	else
		local temp=$[ $1-1 ]
		local result=`factorial $temp`
		echo $[ $result*$1 ]
	fi
}
read -p "Enter value>" value
result=`factorial $value`
echo "The factorial of $value is: $result"
  • 创建库:source命令。source命令在当前shell环境中执行命令,而非创建新shell来执行命令。使用source命令在shell脚本内部运行库文件脚本。这样脚本可以使用这些函数。source有一个短小的别名,成为点操作符。为了在脚本中调用test库文件,只需添加下列命令行:. ./test:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    #!/bin/bash
#test库文件
addem(){
	echo $[ $1+$2 ]
}
multem(){
	echo $[ $1*$2 ]
}
divem(){
	#if [ $2 -ne 0 ]
	#then 
		echo $[ $1 / $2 ]
	#else
	#	echo -1
#	fi
}#以上是库文件
#!/bin/bash
#调用库函数
. ./test-lib
a1=10
a2=4
result1=`addem  a1 a2`
result2=`multem a1 a2`
result3=`divem a1 a2`
echo "The result of adding them is: $result1"
echo "The result of multiplying them is: $result2"
echo "The result of dividing them is $result3"