脚本

目录
程序员经常会使用脚本来方便自己的开发,不过本人脑子记性不好,在此记录一些经常使用的模板。
bash
文本处理
逐行读取文件
FILE=/home/user/file.txt
cat $FILE | while read line
do
echo "line: $line"
done
Json 数据解析
先下载了一个工具:jq
echo "{\"firstName\": \"John\",\"lastName\": \"Smith\"}" | jq '.firstName'
数据计算
浮点除法需要设置小数点位数
echo "scale=10; 89.0 / 1000" | bc
数据比较
V=-120.12
echo "$V < -180.0" | bc
时间转换
ts -> time
date -d @12313 +"%F %T"
控制输入
输入参数
if [ -z $1 ]; then
echo $"Usage: $0 in"
exit 1
fi
echo "in: $1"
等待输入参数:
if read -t 10 -p "wait input: " indata ## 10 秒超时
then
echo "input:$indata"
else
echo "timeout"
fi
判断权限
if [[ $EUID -ne 0 ]]; then
echo Only root can access run
exit 1
fi
命令选择
rc=0
case "$1" in
hello)
echo "hello world"
;;
*)
echo $"Usage: $0 {hello}"
exit 2
esac
exit $rc
判断运行结果
do_or_die()
{
eval $* || exit $?
}
do_or_die echo "Hello"
多次尝试
RET=0
result() {
eval $*
RET=$?
}
loop() {
n=0
until [ $n -ge 3 ]
do
echo "TRY IT $n TIMES ..."
result $*
if [ $RET == 0 ]; then
break
fi
echo "RET IS $RET ..."
n=$[$n+1]
done
}
expect
交互式脚本常用,调试可加上 -d
参数定位问题原因
常用
函数
proc func_name { argc } {
puts $argc
}
func_name "hello"
如果多个函数公用一个 spawn
怎么办?
一种是使用 upvar spawn_id
引入全局变量1:
proc expect_prompt {} {
upvar spawn_id spawn_id
expect -re {bash-[.0-9]+[#$] $}
}
proc open_conn {} {
upvar spawn_id spawn_id
spawn bash --noprofile --norc
expect_prompt
}
proc close_conn {} {
upvar spawn_id spawn_id
send "exit\r"
expect eof
}
proc send_cmd { cmd } {
upvar spawn_id spawn_id
send "$cmd\r"
expect_prompt
}
proc main {} {
open_conn
send_cmd "echo spawn_id=$spawn_id"
send_cmd "ps Tu"
close_conn
}
main
另一种是函数只对 expect
结果进行处理:
proc func {} {
expect {
"xx" { return 0 }
}
return 1
}
spawn xx
if {[func]} {
puts "ERROR"
exit 1
}
expect eof
exit 0
循环
for {set i 0} {$i < 5} {incr i} {
puts "$i"
}
判断
if { true } {
puts "true"
} else {
puts "false"
}
interact2
在结尾加上 interact
表示把控制权交给用户
在 shell 脚本中引用
WORD="hello"
expect <<-EOF
set timeout 10
puts $WORD
puts \$timeout
expect eof
EOF
注意变量和一些特殊字符转义问题
两步验证3
需要安装 oathtool
spawn ssh $USER@$IP
expect {
"(yes/no)?" { send "yes\r"; exp_continue }
"Verification code:" {
set verifi_code [exec oathtool --totp -b -d 6 $SECRETE_KEY]
send "\$verifi_code\r"; exp_continue
}
"password:" { send "$PASSWD\r" }
timeout { exit 127 }
}
expect eof
catch wait result
exit [lindex \$result 3]
获取输入参数4
set user [lindex $argv 0]
set ip [lindex $argv 1]
set len [llength $argv]