《Linux Shell脚本攻略》 第一章小结
1.1脚本格式: 1
1.2脚本执行: 1
1.3终端打印: 1
1.4环境变量 2
1.5 数字运算 3
1.6文件描述符和重定向 4
1.7数据以及关联数组 4
1.8 别名 5
1.9 获取终端信息 5
1.10 获取时间 6
1.11调试脚本 7
1.12 函数与参数 7
1.13 读取命令序列的输出 8
1.14 以不按回车方式读取字符 8
1.15字段分隔符与迭代器 8
1.16 比较与测试 9
1.1脚本格式:
shell脚本第一行:
#!/bin/bash
1.2脚本执行:
sh test.sh
./test.sh
1.3终端打印:
echo hello world!
echo “hello world!”
echo ‘hello world!’ ==>bash不会对$var变量求值。
[root@localhost script]# echo "hello world !"
-bash: !": event not found
[root@localhost script]# echo 'hello world !'
hello world !
[root@localhost script]#
[root@localhost script]# echo 'hello world \!'
hello world \!
[root@localhost script]# var="hi"
[root@localhost script]# echo "$var"
hi
[root@localhost script]# echo '$var'
$var
[root@localhost script]# echo $var
hi
[root@localhost script]#
#'%-5s' - 代表左对齐,字符宽度为5
#'%-4.2f' .2 代表保留两位小数
[root@localhost script]# printf "%-5s %-10s %-4s\n" NO name mark
NO name mark
[root@localhost script]# printf "%-5s %-10s %-4.2f\n" 1 sarath 80.3456
1 sarath 80.35
[root@localhost script]#
[root@localhost script]# echo -n "1\t2\t3" ==》 去除行尾的换行符
1\t2\t3[root@localhost script]# echo "1\t2\t3"
1\t2\t3
[root@localhost script]# echo -e "1\t2\t3" ==》包含转义字符的字符串
1 2 3
[root@localhost script]#
1.4环境变量
打印进程的环境变量
[root@localhost script]# ps
PID TTY TIME CMD
2626 pts/0 00:00:00 bash
3257 pts/0 00:00:00 ps
[root@localhost script]# cat /proc/2626/environ
USER=rootLOGNAME=rootHOME=/rootPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/binMAIL=/var/mail/rootSHELL=/bin/bashSSH_CLIENT=192.168.0.101 61908 22SSH_CONNECTION=192.168.0.101 61908 192.168.0.102 22SSH_TTY=/dev/pts/0TERM=vt100SELINUX_ROLE_REQUESTED=SELINUX_LEVEL_REQUESTED=SELINUX_USE_CURRENT_RANGE=XDG_SESSION_ID=1XDG_RUNTIME_DIR=/run/user/0[root@localhost script]#
[root@localhost script]# cat /proc/2626/environ | tr ‘\0’ ‘\n’ ==》使用’\n’替换 ‘\0’
USER=root
LOGNAME=root
HOME=/root
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
MAIL=/var/mail/root
SHELL=/bin/bash
SSH_CLIENT=192.168.0.101 61908 22
SSH_CONNECTION=192.168.0.101 61908 192.168.0.102 22
SSH_TTY=/dev/pts/0
TERM=vt100
SELINUX_ROLE_REQUESTED=
SELINUX_LEVEL_REQUESTED=
SELINUX_USE_CURRENT_RANGE=
XDG_SESSION_ID=1
XDG_RUNTIME_DIR=/run/user/0
[root@localhost script]#
[root@localhost script]#
环境变量:没有在当前进程中定义,从父进程中继承而来的。
export var ==》当前shell脚本执行的任何程序都会继承这个变量
1.5 数字运算
let (()) [] expr bc
/--------------->/
#! /bin/bash
no1=4
no2=5
let result=no1+no2 <===>result=$[ no1 + no2 ]
echo $result
/<---------------/
let no1++
let no1--
let no1+=6 <===>result=$[ $no1 + 6 ]
result=$((no1+50))
let no1-=6
result=`expr 3+4`
result=$(expr $no1 + 5)
#借助bc实现浮点运算
echo "4 * 0.56" | bc
#设定小数精度(scale=2保留两位小数)
echo "scale=2;3 | bc
#进制转换
no=100
echo "obase=2;$no" | bc
no=1100100
echo "obase=10;base=2;$no" | bc
#计算平方以及平方根
echo "sqrt(100)"| bc #square root
echo "10^10" bc #square
no=50
result=`echo "$no * 1.5" | bc`
1.6文件描述符和重定向
stdin 0
stdout 1
stderr 2
> === 1>
>> === 1>>
echo $? #上一个命令是否成功
cmd 2>stderr.txt 1>stdout.txt
#将stderr转换成stdout,然后输出到同一个文件
cmd 2>&1 output.txt
#tree将标准信息重定向到文件:-a 追加
touch a1
chmod 000 a1
cat a* | tree -a out.txt | cat -n
#重定向脚本内部的文件块
#! /bin/bash
cat <<EOF > log.txt
this is test!!!
this is test!!!
EOF
#使用文件描述符3打开并读取文件
exec 3<input.txt
echo this is a tset line> input.txt
cat <&3 #读取文件
1.7数据以及关联数组
array_var={1 2 3 4 5 6}
array_var[0]="test1"
array_var[1]="test2"
array_var[2]="test3"
...
echo ${array_var[0]}
index=5
echo ${array_var[$index]}
#打印出所有的值
echo ${array_var[*]}
echo ${array_var[@]}
#关联数组
declare -A ass_array
ass_array=([index1]=val1 [index1]=val2)
ass_array=[index1]=val1
ass_array=[index2]=val2
#example
declare -A fruits_value
fruits_value=([apple]='100dollars' [orange]='150 dollars')
echo "Apple costs $(fruits_value[apple])"
echo $(!array_var[*])
echo $(!array_var[@])
1.8 别名
alias new_command='command sequence'
alias instll='sudo apt-get instll'
unalias
alias rm='cp $@ ~/backp; rm $@'
\command #忽略别名
1.9 获取终端信息
tput stty
#获取终端行号与列号
tput cols
tput lines
#打印终端名
tput longname
#移动光标
tput cup 100 100
1.10 获取时间
date
date +%s ===>自1970-01-01:0以来的秒数。(UTC:coordinated universal time)
date --date "Thu Nov 18 08:07:21 IST 2010" +%s ===》将日期转换成秒数
date --date "Jan 20 2001" +%A ===>转换为星期
%a %A 星期
%b %B 月
%d 天数
%D 固定格式日期(mm/dd/yy)
%y %Y 年
%I %H 小时
%M 分钟
%S 秒
%N 纳秒
%s UNIX纪元时(1970-01-01:0:0)
date "+%d %B %Y"
#检查一组命令花费的时间
#!/bin/bash
start=$(date +%s)
commands;
end=$(date +%s)
difference=$((end - start))
#计数
#!/bin/bash
echo -n count;
tput sc
count=0;
while true;
do
if [ $count -lt 40 ];then
let count++;
sleep 1;
tput rc ==》恢复光标的位置
tput ed ===》清除光标位置到行尾的所有内容。
echo -n $count
else
exit 0;
fi
done
1.11调试脚本
bash -x script.sh
set -x 在执行时显示参数和命令
set +x
set -v 当命令进行读取时显示输入
set +v
#!/bin/bash -xv
#!/bin/bash
function DEBUG()
{
[ "$_DEBUG" == "on" ] && $@ || :
}
for i in (1..10)
do
DEBUG echo $i
done
$ _DEBUG=on ./script.sh
1.12 函数与参数
fname()
{
echo $1, $2
echo "$@" 被扩展成"$1" "$2" "$3"
echo "$*" 被扩展成"$1c$2c$3",其中c是IFS的第一个字符
return 0
}
#导出函数
export -f fname
1.13 读取命令序列的输出
ls | cat -n > out.txt ==>管道
cmd_output=$(COMMANDS) ==>子shell方式
cmd_output=`COMMANDS`
#子shell是一个独立的进程
pwd
(cd /bin;ls)
pwd
1.14 以不按回车方式读取字符
read -n number_of_chars variable_name
#example
read -n 2 var
#不回显得方式读取密码:
read -s var
#显示提示信息
read -p "Enter input:" var
#在特定的时间内读取输入:
read -t timeout var
#用定界符结束输入行:
read -d delim_charvar
#example
read -d ":" var
1.15字段分隔符与迭代器
内部字段分隔符(Internal Field Separator, IFS)
IFS时存储定界符的环境变量
#!/bin/bash
line="root:x:0:0:root:/root:/bin/bash"
oldIFS=$IFS
IFS=":"
count=0
for item in $line
do
[ $count -eq 0 ] && user=$item;
[ $count -eq 6 ] && shell=$item;
done
IFS=$oldIFS
echo $user\'s shell is $shell
for i in {a..z}; do actions;done;
for i in {1..50}; do actions; done;
for((i=0;i<10;i++))
{
commands;
}
while condition
do
commands;
done
x=0
until [ $x -eq 9 ];
do
let x++;echo $x;
done
1.16 比较与测试
if condition;then
commands
fi
if condition;then
commands
elif condition
commands
else
commands
fi
#如果condition为真,则执行action
[ condition ] && action;
#如果condition为假,则执行action
[ condition ] || action;
#算数比较
[ $var -eq 0 ] or [ $var -eq 0 ]
-gt -lt -ge -le
#逻辑与-a
[ $var1 -ne 0 -a $var2 -gt 2 ]
#逻辑或 -o
[ $varl -ne 0 -o $var2 -gt 2 ]
#文件系统相关测试
[ -f $file_var ] ==>文件是否存在
[ -x $var ]
-d
-e
-c
-b
-w
-r
-L
#字符串比较
[[ $str1 = $str2 ]]
[[ $str1 == $str2 ]]
[[ $str1 > $str2 ]]
[[ -z $str1 ]] ==>如果str1包含的是空字符串,则返回真
if [[ -n $str1 ]] && [[ -z $str2 ]] ;then
commands
fi