1、shell变量
变量赋值需注意一点等号两边不允许空格;在使用变量时,需在变量前加“$变量”符号或“${变量}(可选)”;
#例如一个for循环
for skill in Ada Coffe Action Java; do
echo "I am good at ${skill}Script"
done
#字符串变量,"" or ''
my_string='Hello, World!'
my_string="Hello, World!"
#整数变量,可以使用 declare 或 typeset 命令来声明整数变量
declare -i my_integer=42
#数组变量
my_array=(1 2 3 4 5)
#环境变量
echo $PATH
#特殊变量
$0 表示脚本的名称
$1, $2, 等表示脚本的参数
$# 表示传递给脚本的参数数量
$? 表示上一个命令的退出状态
$- 显示Shell使用的当前选项
$$ 脚本运行的当前进程ID
2、传递参数
在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为 $n,n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数。
[root@localhost ~]# cat test.sh
#!/bin/bash
echo "Shell 传递参数实例!";
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
[root@localhost ~]# ls -l test.sh
-rw-r--r-- 1 root root 23735 Feb 11 11:24 test.sh
[root@localhost ~]# chmod 775 test.sh
[root@localhost ~]# ./test.sh 1 2 3
Shell 传递参数实例!
执行的文件名:./test.sh
第一个参数为:1
第二个参数为:2
第三个参数为:3
3、数组
数组中可以存放多个值。Bash Shell 只支持一维数组(不支持多维数组);与大部分编程语言类似,数组元素的下标由 0 开始。Shell 数组用括号来表示,元素用"空格"符号分割开。
array_name=(value1 value2 ... valuen)
#!/bin/bash
my_array[0]=A
my_array[1]=B
my_array[2]=C
my_array[3]=D
echo "数组的元素为: ${my_array[*]}"
echo "数组的元素为: ${my_array[@]}"
4、运算符
4.1、算术运算符
注意:条件表达式要放在方括号之间,并且要有空格,例如: [$a==$b] 是错误的,必须写成 [ $a == $b ]。
#!/bin/bash
a=10
b=20
# 加
val=`expr $a + $b`
# 减
val=`expr $a - $b`
# 乘
val=`expr $a \* $b`
# 除
val=`expr $b / $a`
# 取余
val=`expr $b % $a`
if [ $a == $b ] # 相等
then
echo "a 等于 b"
fi
if [ $a != $b ] # 不等
then
echo "a 不等于 b"
fi
4.2、关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
#!/bin/bash
if [ $a -eq $b ]
then
echo "$a -eq $b : a 等于 b"
fi
if [ $a -ne $b ]
then
echo "$a -ne $b: a 不等于 b"
fi
if [ $a -gt $b ]
then
echo "$a -gt $b: a 大于 b"
fi
if [ $a -lt $b ]
then
echo "$a -lt $b: a 小于 b"
fi
if [ $a -ge $b ]
then
echo "$a -ge $b: a 大于或等于 b"
fi
if [ $a -le $b ]
then
echo "$a -le $b: a 小于或等于 b"
fi
4.3、布尔运算符
| 运算符 | 说明 | 举例 |
|---|---|---|
| ! | 与 | [ ! false ] 返回 true |
| -o | 或 | [ $a -lt 20 -o $b -gt 100 ] 返回 true |
| -a | 与 | [ $a -lt 20 -a $b -gt 100 ] 返回 false |
4.4、逻辑运算符
&&:逻辑的与
||:逻辑的或
#!/bin/bash
a=10
b=20
if [[ $a -lt 100 && $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
if [[ $a -lt 100 || $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
4.5、字符串运算符
| 字符串比较 | 释义 |
|---|---|
| If [ a = b ] | 如果string1等于string2,则为真 |
| if [ string1 != string2 ] | 如果string1不等于string2,则为真 |
| if [ -n $string ] | 如果string 非空(非0),返回0(true) |
| if [ -z $string ] | 如果string 为空,则为真 |
| if [ $sting ] | 如果string 非空,返回0 (和-n类似) |
4.6、文件测试运算符
| 表达式 | 表达式释义 |
|---|---|
| -e Filename | 如果Filename存在,则为真 |
| -r Filename | 如果Filename可读,则为真 |
| -w Filename | 如果Filename可写,则为真 |
| -x Filename | 如果Filename可执行,则为真 |
| -d Filename | 如果Filename为目录,则为真 |
| -f Filename | 如果Filename为常规文件,则为真 |
| -L Filename | 如果Filename为符号链接,则为真 |
| -s Filename | 如果文件长度不为0,则为真 |
| -h Filename | 如果文件是软连接,则为真 |
| Filename1 -nt Filename2 | 如果Filename1比Filename2新,则为真 |
| Filename1 -ot Filename2 | 如果Filename1比Filename2旧,则为真 |
4.7、自增自减操作符
#!/bin/bash
# 自增
let num++
# 自减
let num--
# 使用 $(( ))
num=$((num + 1))
num=$((num - 1))
# 使用 expr
num=$(expr $num + 1)
num=$(expr $num - 1)
# 使用 (( ))
((num++))
((num--))
5、流程控制
在流程控制中有时候需要在未达到循环结束条件时强制跳出循环,Shell 使用两个命令来实现该功能:break 和 continue;
5.1、Linux下使用for循环的几种使用格式
1、for((i=1;i<10;i++)); do #常用
~
done
2、for i in $(seq 1 10); do
~
done
3、for i in {1..10}; do
~
done
# 无限循环
4、for (( ; ; )); do
~
done
#awk应用
5、awk 'BEGIN{for(i=1;i<10;i++) print i}
5.2、Linux下使用if判断的格式
#文件存在且变量不为零,逻辑与
[ -e $load/fiotesf.log -a $loops -eq 0 ]
[[ -e $load/fiotesf.log && $loops -eq 0 ]]
[[ -eq $load/fiotesf.log ]] &&[[ $loops -eq 0 ]]
[ -eq $load/fiotesf.log ]&&[ $loops -eq 0 ]
#if语句格式
if condition; then
commands;
elif condition; then
commands;
else
commands;
fi
#使用&&和 ||也可以达到if else效果
[ condition ] && commands || commands
例:a等于8,则打印True,否则Failed
[root@localhost #] a=8;[ a -eq 8 ] && echo Ture || echo Failed
True
5.3、Linux下使用while语句的格式
while condition
do
command
done
# 无限循环
while : or while true
do
command
done
5.4、Linux下使用until语句的格式
执行一系列命令直至条件为 true 时停止
#!/bin/bash
a=0
until [ ! $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done
5.5、Linux下使用case语句的格式
case ... esac 为多选择语句,与其他语言中的 switch ... case 语句类似,是一种多分支选择结构,每个 case 分支用右圆括号开始,用两个分号 ;; 表示 break,即执行结束,跳出整个 case ... esac 语句,esac(就是 case 反过来)作为结束标记
case 值 in
模式1)
command1
command2
...
commandN
;;
模式2)
command1
command2
...
commandN
;;
esac
# 示例
echo '输入 1 到 4 之间的数字:'
echo '你输入的数字为:'
read aNum
case $aNum in
1) echo '你选择了 1'
;;
2) echo '你选择了 2'
;;
3) echo '你选择了 3'
;;
4) echo '你选择了 4'
;;
*) echo '你没有输入 1 到 4 之间的数字'
;;
esac
6、函数
可以带 function fun() 定义,也可以直接 fun() 定义,不带任何参数。
参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return 后跟数值 n(0-255).
注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。
注意: return 语句只能返回一个介于 0 到 255 之间的整数,而两个输入数字的和可能超过这个范围。
[ function ] funname [()]
{
action;
[return int;]
}
7、输入输出重定向
| 表达式 | 表达式释义 |
|---|---|
| command > file | 将输出重定向到 file |
| command < file | 将输入重定向到 file |
| command >> file | 将输出以追加的方式重定向到 file |
| n > file | 将文件描述符为 n 的文件重定向到 file |
| n >> file | 将文件描述符为 n 的文件以追加的方式重定向到 file |
| n >& m | 将输出文件 m 和 n 合并 |
| n <& m | 将输入文件 m 和 n 合并 |
| << tag | 将开始标记 tag 和结束标记 tag 之间的内容作为输入 |
注意:0 是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。这里的 2 和 > 之间不可以有空格,2> 是一体的时候才表示错误输出。
例:command > /dev/null 2>&1
8、shell脚本
#! /usr/bin/bash
data=`date +"%Y-%m-%d_%H-%M-%S"`
TEMP_DIR='/backup'
MESSAGE_DIR='/var/log/message'
if [[ ! -d $TEMP_DIR ]]; then
echo "临时目录 $TEMP_DIR 不存在,正在创建 ..."
mkdir -p $TEMP_DIR
fi
function GetParameter(){
while getopts "s:d:n:" opt; do
case $opt in
s)
SOURCE_DIR="$OPTARG"
;;
d)
TARGET_DIR="$OPTARG"
;;
n)
BACKUP_NAME="$OPTARG"
;;
*)
echo "用法: $0 -s 原备份文件 -d 目标目录 -n 备份文件名"
exit 1
;;
esac
done
if [[ -z "$SOURCE_DIR" || -z "$TARGET_DIR" || -z "$BACKUP_NAME" ]]; then
echo "错误:缺少必填参数!"
echo "用法: ./clearlog.sh -s 源目录 -d 目标目录 -n 备份文件名"
exit 1
fi
}
function BackUpLog(){
local target_dir=$1
local bakup_name=$2
local source_dir=$3
local backup_file="$target_dir/$bakup_name-$data.tar.xz"
if [[ ! -d $target_dir ]]; then
echo "目标目录 $target_dir 不存在,正在创建 ..."
mkdir -p $target_dir
fi
echo "正在备份 $source_dir 到 $target_dir ..."
if [[ -z $MESSAGE_DIR ]];then
echo "备份message ..."
cp -rv $MESSAGE_DIR $TEMP_DIR
fi
echo "备份dmesg ..."
dmesg -T > $TEMP_DIR/dmesg
echo "备份$source_dir ..."
cp -rv $source_dir $TEMP_DIR
echo "正在压缩文件 ..."
tar -cJvf $backup_file -P $TEMP_DIR
if [[ $? -eq 0 ]]; then
echo "备份成功!备份文件保存在 $backup_file"
else
echo "备份失败!请检查错误信息。"
exit 1
fi
}
function ClearSourPathLog(){
local message=$1
local source_dir=$2
local temp_dir=$3
echo "正在清除文件 ..."
echo "" > $message
rm -rf $source_dir
rm -rf $temp_dir
dmesg -C
}
function main(){
echo " 开始执行 "
echo "============================================"
echo "获取传入的源路径、目标路径"
GetParameter "$@"
echo "开始进行备份,备份到:$TARGET_DIR"
BackUpLog $TARGET_DIR $BACKUP_NAME $SOURCE_DIR
echo "============================================"
echo "开始清理log,清理路径:$SOURCE_DIR"
ClearSourPathLog $MESSAGE_DIR $SOURCE_DIR $TEMP_DIR
echo "============================================"
unset TARGET_DIR SOURCE_DIR BACKUP_FILE BACKUP_NAME MESSAGE_DIR TEMP_DIR
echo "执行结束!!!"
}
main "$@"
~文章已经结束了~
声明:本人所写的只是本人在使用中遇到的问题做个记录总结,很多内容也是百度,或者查阅官方文档,若与他人有重复;若需按照本文配置,请认真确认是否适合你的情况,造成一切损失;本人概不负责。