linux shell 编程
shell脚本示例:
#!/bin/bash
# note
date
ls
#!指定了该脚本的执行程序是bash
基本内容:
基本输出
echo Hello world
echo "let's go"
输出全局变量
echo $HOME
echo $PATH
输出局部变量
my_var=my_variable
echo $my_var
unset my_var
echo $my_var
字符串中的变量替换
echo "my home is ${HOME}"
echo "my home is $HOME"
捕获命令执行的结果
my_date=`date`
echo $my_date
my_date=$(date)
echo $my_date
重定向管道
rpm -qa|sort > outfile
rpm -qa|sort &> outfile
整数计算
my_res=$[1 + 2]
echo $my_res
my_res2=$[$my_res * 5]
echo $my_res2
浮点数计算,利用bc命令计算,EOF是命令体分隔符
var1=10.46
var2=43.67
var3=33.2
var4=71
var5=$(bc << EOF
scale=4
al=($var1 *$var2)
b1=($var3*$var4)
al+b1
EOF
)
分支语句
if-then-else
if command
then
commands
else
commands
fi
if command1
then
commands
elif command2
then
more commands
fi
test命令
test condition
if test condition
then
commands
fi
#更常用的test形式:
if [ condition ]
then
commands
fi
test命令可判断的三类条件:数值比较, 字符串比较, 文件比较
#数值比较:
n1 -eq n2
n1 -ge n2
n1 -gt n2
n1 -le n2
n1 -lt n2
n1 -ne n2
#数值比较示例
if [ $v1 -eq $v2 ]
then
echo eq
else
echo diff
fi
#字符串比较
s1 = s2
s1 != s2
s1 < s2
s1 > s2
-n s1 #检查s1长度不为0
-z s1 #检查字符长度是否是0
实际使用中要对>进行转义,防止重定向冲突
#文件比较
-d file #是否存在并且是目录
-e file #是否存在
-f file #是否存在并且是文件
-r file #是否存在并且可读
-s file #是否存在并且非空
-w file #是否存在并且可写
-x file #是否存在并且可执行
-O file #是否存在并且属于当前用户
-G file #是否存在并且默认组与当前用户相同
file -nt file2 #file是否比file2新
file -ot file2 #file是否比file2旧
#文件比较示例
if [ -d $file_dir ]
then
echo file dir exists
else
echo file does not exists
fi
#符合测试条件
if [ -d $HOME ] && [ -w $HOME/testing ]
then
echo "-----"
else
echo "-----"
fi
if-then高级特性
使用(())用于数学表达式
使用[[]]用于高级字符串处理功能
if (( $val1 ** 2 > 90 ))
then
((val2=$val1**2))
echo "val2=$val2"
fi
if [[ $USER == r* ]]
then
echo "Hello $USER"
else
echo "Sorry"
fi
case 命令
case $USER in
rich | barbara)
echo "welcome $USER"
testing)
echo "testing account"
*)
echo "Sorry"
esac
for命令
for var in list
do
commands
done
for test in a b c d e f
do
echo $test
done
for test in $(cat $file)
do
echo $test
done
指定字段分割符:
IFS=$'\n' #换行符
IFS=$'\n':;" #指定多个分隔符
使用通配符匹配目录:
for file in /home/*
do
echo $file
done
while命令
while [ $var1 -gt 0 ]
do
echo $var1
done
until命令
until [ $var1 -eq 0 ]
do
echo $var1
done
控制循环
break
break 2
continue
continue 2
处理循环的输出
for file in $HOME/*
do
echo $file
done > output.txt
命令行参数
$0 是脚本名 $1 第一个参数 $2 …
$# 脚本运行时携带的命令行参数的个数
$* 所有参数的字符串
$@ 所有参数分割到数组中
shift 往左移动一个变量
getopt命令
参数分解
getopt ab:cd -a -b test1 -cd test2 test3
-a -b test1 -c -d -- test2 test3
在脚本中使用getopt
set命令的-- 选项会替换输出内容变为当前脚本的参数
set – (getopt−qab:cd"(getopt -q ab:cd "(getopt−qab:cd"@")
更高级命令:getopts每次调用返回一个参数
while getopts :ab:c opt
do
case "$opt" in
a) echo ----
b) echo "foud -b ,with value $OPTARG"
c) echo ----
*) echo "unknown"
esac
done
永久重定向
exec 1>testout
创建临时文件:
mktemp testing.XXXXXX
信号处理
linux的常用信号:
1 挂起进程
2 种植进程
9 无条件终止进程
15 尽可能终止进程
捕获信号:
trap commands signals
trap "echo 'Sorry!'" SIGINT
sed命令
sed命令格式如下:
sed options script file
-e 选项允许使用多个命令
替换命令:
sed -e '
s/brown/green/
s/fox/elephant/
s/dog/cat/' data1.txt
加倍行间距G命令
sed '$!G' data2.txt
删除连续的空白行:使用正则匹配地址,加排他命令执行删除
sed '/./,/^$/!d' data8.txt
删除行:
sed '2,3d' data6.txt
插入和附加文本:命令i,a
sed '3i\
this is aaaaa' data6.txt
sed '3a\
this is bbbbb' data6.txt
修改行:c命令
sed '3c\
this is cccc.' data6.txt
sed '/number 3/c\
this is number change' data6.txt
回顾打印命令:
p用来打印文本行
=用来答应行号
l用来列出行
sed -n '/number 3/p' data6.txt
gawk命令
语法:
gawk options program file
选项:
-F fs 指定文件分隔符
gawk '{print "Hello world"}'
使用数据字段变量:
$0 代表整个文本行
$1 代表文本行的第一个数据字段
$n 代表文本行的第n各字段
gawk '{print $1}' data2.txt
gawk -F: '{print $1}' /etc/passwd
gawk '{
$4="char"
print $0}'
my name is aaaaa
参考书籍:Linux命令行与Shell脚本编程