Bash 脚本学习
2021年9月2日 · 1282 字 · 3 分钟
工作和生活中用的电脑都是 ubuntu(18.04)
系统,时不时需要编写一些 Bash
脚本,目的当然是为了减少重复作业。为了避免每次都 临时
和 低效
地检索,索性自己整理一下。互联网中资料是海量的,但是垃圾信息也越来越多了,感觉现在上网找答案都好难,到处都是广告,无脑转载,标题党……
$? $$ $# $@ $* $1
#!/bin/bash
ls
(( $? == 0 )) && echo "ok" || echo "error"
echo "I was called with $# parameters"
echo "My name is [$0]"
echo "My first parameter is [$1]"
echo "My second parameter is [$2]"
echo "All parameters are [$@]"
echo "All parameters are [$*]"
echo "PID is [$$]"
$#
实际参数个数$0
脚本自己的名字$@ $*
所有参数$1 $2
具体第几个参数$$
PID
测试如下:
❯ bash ./temp.sh one 2 さん 四
I was called with 4 parameters
My name is [./temp.sh]
My first parameter is [one]
My second parameter is [2]
All parameters are [one 2 さん 四]
All parameters are [one 2 さん 四]
PID is [7958]
set
set 命令是 Bash 脚本的重要环节,却常常被忽视,导致脚本的安全性和可维护性出问题.
## 脚本只要发生错误,就终止执行。
set -e
## 脚本在头部加上它,遇到不存在的变量就会报错,并停止执行。
set -u
## 用来在运行结果之前,先输出执行的那一行命令。
set -x
变量 && 数组
pai=3.1415
name="桃田賢斗"
number=9527
arr1=( $(ls) ) ## 数组声明 枚举
arr2=(1 2 3 4) ## 数组声明 枚举
arr2+=("5" "6") ## 增加元素
echo "$pai $name $number ${arr1[@]} ${arr2[@]}"
判断
if
字符串比较
l=abc
r="abc"
[[ $l == $r ]] && echo "$l == $r"
r="abcd"
[[ $l != $r ]] && echo "$l != $r"
l=abcde
[[ $l == *$r* ]] && echo "$l == *$r*"
#### 判断当前系统(OS)
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
# ...
elif [[ "$OSTYPE" == "darwin"* ]]; then
# Mac OSX
elif [[ "$OSTYPE" == "cygwin" ]]; then
# POSIX compatibility layer and Linux environment emulation for Windows
elif [[ "$OSTYPE" == "msys" ]]; then
# Lightweight shell and GNU utilities compiled for Windows (part of MinGW)
elif [[ "$OSTYPE" == "win32" ]]; then
# I'm not sure this can happen.
elif [[ "$OSTYPE" == "freebsd"* ]]; then
# ...
else
# Unknown.
fi
## 判断某文件是否存在某个字符串, 单行书写,可以在 控制台执行
if grep -q "string" file; then echo ok; fi
数字比较
one=1
two=2
(( $one >= $two )) && echo "$one >= $two"
(( $one <= $two )) && echo "$one <= $two"
(( $one == $two )) && echo "$one == $two"
(( $one > $two )) && echo "$one > $two"
(( $one < $two )) && echo "$one < $two"
## 判断 当前用户是否为 root,或者是否有 root 权限
if (( $EUID != 0 )); then
echo "[ERROR] This script must be run as root!"
else
echo "ok, run as root!!!"
fi
判断文件/目录是否存在
if [ -d "$dir" ]; then
echo "have dir $dir"
fi
if [ -f "$file" ]; then echo "have file $file"; fi
NULL ?
[[ -z "$my_var" ]] && echo "\$my_var is NULL"
纯数字 ?
X=fasdf3213
echo $X | grep "[^0-9]" > /dev/null 2>&1
(( $? == 0 )) && echo "not number" || echo "number"
case
arr=(1 2 3 5 8 13)
for i in ${arr[@]}; do
case $i in
1|2|3) echo $i "=> 1|2|3";;
4|5|6) echo $i "=> 4|5|6";;
8) echo $i "=> 8";;
*) echo $i "=> *";;
esac
done
循环
for
#!/bin/bash
array=(1 2 3 4) ## 数组声明 枚举
for i in "${array[@]}"; do # 遍历数据
echo $i
done
for i in {10..20}; do ## 描述式数组
echo $i
done
str="I am robot!" ## 遍历字符串
for s in $str; do
echo $s
done
while
i=0
while (( i < 10 )); do
(( ++i )) && echo -en "$i "
done
echo "----------------------"
while :; do
(( ++i ))
(( i < 20 )) && echo -en "$i " || break
done
函数
main () {
echo "$1"
echo "hello world~"
return 256 ## 最大返回 255
}
get_str () { str="Alice"; }
main "$@" "other arguments"
echo $?
get_str "$@"
echo $str
关键字
shift 迭代
while [[ "$#" -gt 0 ]]; do
case $1 in
-s|--stop) echo "need stop" ;;
-l|--log) echo "show log" ;;
*) echo "Unknown parameter passed: $1"; exit 1 ;;
esac
shift
done
read 命令行读取
read X && echo $X
IFS 分割符
old_IFS="$IFS"
IFS=:
echo "Please input some data seqarated by colons"
read x y z
IFS=$old_IFS
echo "x is $x; y is $y; z is $z"
trap 捕捉 signal
say_hi () {
echo "おはよう"
}
trap 'say_hi' HUP
int i=0;
while (( i<10 )); do
sleep 1
(( ++i ))
echo $i
done
exit 退出脚本
exit 0
echo "exit" ## 不会执行
脚本
遍历当前目录
for i in *; do
ls -l $i
done
array=( $(ls) )
for i in ${array[@]}; do
ls -l $i
done
以“行”为单位读取文件,但是最后一行貌似不会读取
while read f
do
case $f in
hello) echo English ;;
howdy) echo American ;;
gday) echo Australian ;;
bonjour) echo French ;;
"guten tag") echo German ;;
*) echo Unknown Language: $f ;;
esac
done < myfile
ICON 反色处理
array=( $( ls | grep png) )
for png in ${array[@]}
do
echo $png
convert $png -channel RGB -negate $png.white.png
done
线路探测 ./xx.sh
line=`nslookup $1 | grep Address: | grep -o " .*" | sed 's/\ //g'`
line=`echo $line | sed 's/\ /,\ /g'`
echo $line
IFS=', ' read -r -a array <<< ${line}
for element in "${array[@]}"
do
msg='{"cmd":"reqServer", "rServerAddr":"'${element}':'$2'", "pid":"'`date +"%s"`'", "seq":1, "sendTime":'1555379390294532000'}'
echo "[C-->S] : $msg"
echo -en '[C<--S] : '
echo -n $msg | nc -u -w1 ${element} $2
echo ''
done