Linux命令行与shell脚本编程大全(shell脚本编程基础部分)

第十一章 构建基本脚本

  • #为注释,但#!在第一行中后可以接shell的种类;如#!/bin/bash 会告诉shell用哪个shell来运行脚本
  • echo -n(显示在同一行中)
  • 环境变量:set
  • 用户变量 var=10 中间不能加空格;引用变量值时要用美元符$;赋值时不用
  • 将命令输出赋给变量: ` ` 和$( ) 如test=$(date) 这会进行命令替换,命令替换会创建一个子shell来运行对应的命令,由该子shell所执行的命令是无法使用脚本中所创建的变量的
  • 在命令行提示符下使用路径./运行命令的话,也会创建出子shell;如果不加路径,就不会创建子shell;使用内建的shell命令不会涉及到子shell
  • 输出重定向: > 如date > test1 会覆盖当前文件的内容
  • >>可以来追加数据到已有文件中
  • 输入重定向: < 如 wc < test1
  • 内联输入重定向符号 << 如wc << EOF(任意值且需首位呼应)
  • 管道: 如 rpm -qa | sort | more
  • expr var1=$[$var2+5] bash shell运算符只支持整数运算
  • bc 脚本中使用bc: var1=$(echo “scale=4; 3.44/5” |bc)下面为多行格式利用bc
var1=10.46
var2=43.67
var3=33.2
var4=71

var5=$(bc << EOF
scale = 4
a1 = ( $var1 + $var2)
b1 = ( $var3 + $var4)
a1 + b1
EOF
)
  • bash计算器创建的变量只能在bash计算器中使用
  • 退出状态码 $? echo $?
  • 脚本中最后一行可以允许你指定一个退出状态码: exit 5 exit $var1

第十二章 使用结构化命令

  • bash shell的if-then:bash shell的if语句会运行它后面的语句,如果其状态返回码为0则运行then
if pwd
then
	echo " IT WORKED"
fi
###另一种形式
if command; then
	commands
fi
  • if-then-else语句
if command
then
	commands
else
	commands
fi
  • 嵌套if及else部分的另一种形式elif
if command
then
	commands
else
	if command
	then
		commands
	fi
fi
###另一种形式
if command
then
	commands
elif command
then
	commands
elif command
then
	commands
else
	commands
fi
  • test命令(如果不懈test命令的condition部分,它会以非0的退出状态码退出,执行else部分)及[ ];[ ]及test可以比较三类条件:数值比较,字符串比较,文件比较;且[ ]中[ 后和 ]前都必须加一个空格
if test $var1
then
	commands
else
	commands
fi
##[]形式
if [ condition ]
then
	commands
fi
  • 数值比较:n1 -eq或ge,gt,le,lt,ne n2 如if[ $var1 -gt 5 ] 局限:bash shell中只能处理整数,不能对浮点数进行相应的运算,但是如果只用echo显示结果是可以的
  • 字符串比较: str1 =或!=,<,> str2和-n(z) str1需要注意的两个问题:一.大于号和小于号必须转义;二.大于和小于顺序和sort命令所采用的不同;-z判断时如果变量没被定义过也算他长度为0
  • 文件比较
比较 描述
-d file
-e
-f
-r
-s 是否存在且非空
-w
-x
-O
-G
file1 -nt file2
file2 -ot file2
除了最后两个都先检查了文件是否存在
  • 上面的-G会检查文件的默认组,但他只比较用户的默认组而非所有组;只有当用户的默认组刚好匹配时才会成功
  • 复合条件测试:if [ conditon1 ] && [ conditon2 ]或||
  • if-then 的高级特性:一.双括号(())提供高级数学运算 if(( expression )) 如if(( $var1 ** 2 >90 )) 二.双方括号[[ ]]提供了test命令中的标准字符串比较,以及模式匹配(pattern matching)如if [[ $USER == r* ]]
  • case命令
case variable in
pattern1 | pattern2) 
	commands1;;
pattern3)
	commands2;;
*)
	default commands
esac

第十三章 更多的结构化命令

  • for命令
for var in list
do 
	commands
done
  • 在最后一次迭代后,$var变量的值会在shell脚本的剩余部分一直保持有效,且为最后一次迭代的值,除非你修改了他
  • 解决读取列表中的复杂值:如果为’可以用“”或加\来解决,如果有空格的话,可以用“”
  • 从变量读取列表
list="china usa"
list=$list" japan"
for var in $list
do
	echo $var
done
##从命令读取值
file="states"
for state in $(cat $states)
do
	command
done
  • 更改字段分隔符:IFS(空格,制表符,换行符)IFS=$‘\n’:;" 指定了多个分隔符
  • 用通配符读目录
for file in /home/rich/test/* /home/rich/badtest
do
	if[ -d "$file"]
	then 
		echo "$file is a d"
	elif[ -f "$file"]
	then
		echo "$file is a f"
	fi
done
  • c语言风格的for命令 for(( i= 1; i<=10;i++)) 某些部分没有遵循bash shell 的标准for ; 可以使用多个变量,但在for循环中只有一个条件for(( a=1,b=10;a<=10;a++,b–))
  • while until : 只有最后一个测试命令的退出状态码会被用来决定什么时候退出循环,每一个测试命令都在单独的一行上
var1=10
while echo $var1
	[ $var1 -ge 0]
do
	var1=$[ var1-1 ]
done
  • break n 和 continue n
  • 循环可以输出:done后面>和|和<都行

第十四章 处理用户输入

  • ./addem 10 30 传入了两个命令行参数
  • $0(程序名) $1(第一个参数)被称为位置参数;一直到9;之后的用${10}
  • name=$(basename $0)(basename方法获得脚本名)
  • 使用参数时一定检查其中是否存在数据
  • $# 含有脚本运行时携带的命令行参数的个数;${!#}表示最后一个命令行参数
  • $* 将命令行的所有参数当作一个单词保存 ; $@会将其当作一个字符串的多个独立的单词
  • shift n 向左移动命令行参数
  • 分离参数和选项:利用-- 如./test -a -b – test1 test2 在case --的时候shift
  • 处理带值的选项:./test -a -b test1 -d 在case -b 的时候多处理下下个参数
  • read -p var; read -t 5 ; read -n2 ; read -s ; read first last ;read后指定多个变量会让输入的每个数据值都分配给变量列表的下一个变量,数量不够的话,剩的都分配到最后一个变量中,没指定变量的话,会放进$REPLY中; cat test | while read var(一行一行读文件)
  • getopt optstring parameters:如getopt -q ab:cd -a -b test1 -cde test2 test3 脚本中使用:set – $(getopt -q ab:cd “$@”)将格式转为短格式然后利用set – 将其传给所有命令行变量;缺点:无法处理带空格和引号的参数值
  • while getopts ab:c var(case中无-)好处:可以处理带空格参数;./test -abtest1(这种形式甚至也行);getopts用$OPTARG保存选项后的一个参数值;用$OPTIND记录正在处理的参数位置;他处理直到选项处理完为止,之后可以根据$OPTIND的值和shift移动参数

第十五章 呈现数据

  • STDIN STDOUT STDERR
  • ls -al badfile 2> test4 1> test2
  • 输出到同一个文件 &>(错误信息有更高的优先级,显示在上面)
  • 脚本中临时重定向:echo “test” >&2
  • 永久重定向: exec 1>testout exec 2>testerror exec 0< testfile
  • exec 3>&1 exec 1>&3(临时重定向输出,然后恢复)
  • exec 3<> testfile(读写文件描述符,有问题是有一个指针维护当前位置,为读写共用的,可能出现问题)
  • exec 3>&-(关闭)
  • lsof -a -p $$ ad 0,1,2(普通用户要/usr/sbin/lsof)
  • 阻止命令输出: /dev/null ; 也可以用它清楚文件中数据
  • mktemp test.XXXXXX(返回文件名;加-t返回完整路径;加-d表示创建目录)
  • tee -a(追加) : 给STDIN过来的数据发往STDOUT和file
  • p328例子很好:将语句变为sql语句

第十六章 控制脚本

  • shell脚本默认行为是忽略信号;bash shell收到SIGHUP信号后会在退出之前,将SIGHUP传给所有由该shell启动的进程
  • ctrl + c 可以中断进程,相当于SIGINT信号
  • ctrl + z 可以暂停进程,相当于SIGTSTP信号
  • 捕获信号:指定shell脚本监看并从shell中拦截的Linux信号:利用trap命令使信号不再被shell处理,而是交由本地处理 如 trap commands signals
  • 捕获脚本退出: trap commands EXIT
  • trap – SIGINT可以删除已设置好的捕获
  • 后台运行脚本:./test &(用终端显示STDOUT STDERR)如果终端会话退出,后台进程也会随之退出
  • nohup命令运行另外一个命令来阻断所有发送给改进程的SIGHUP信号,会在退出终端会话时阻止进程退出;如 nohup ./test & 会自动将STDOUT STDERR重定向到nohup.out的文件中
  • jobs -l 显示出的 + -的意义(默认作业 和 下一个默认作业)
  • bg 5(作业号) fg 2
  • nice -n 10 renice -n 10 -p 5055调度优先级从-20到+19(低优先级)
  • at [-f filename] time at采用e-mail方式传递STDOUT和STDERR,最好进行重定向; atq atrm 18(作业号)
  • cron时间表: min hour dayofmonth month dayofweek command 如 15 10 * * * command
  • crontab -l cron目录:hourly daily monthly weekly,如果要脚本每天执行一次,只要将脚本复制到daily目录
  • anacron运行错过的作业(只在cron目录里的,而且一天以上间隔的) peropd delay identifier command

你可能感兴趣的:(linux,服务器,bash)