这两天复习了一下shell的一些基本操作。直接上脚本。

另附附件。

#! /bin/bash

# 演示一下here document重定向。
# 它的基本的形式如下:
# command << delimiter
#    document
#delimiter
#它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command。

cat << EOF
简单学习回顾shell知识。
这个shell脚本是单纯的练习用脚本。
将shell的一些基本语法知识放到这里面来实践。
函数的部分另外放在一个文件中【其实内容并不多】。
主要参考:网上的菜鸟教程
EOF

# 变量名和=之间不能有空格。
myName="yudian"
echo "hello world ${myName}!"

# 简单的for循环写法
for file in ls
do
echo ${file}
done

# 只读变量
single="stop"
readonly single
echo "${single}"
single="run"
echo "${single}"

# 删除变量;unset 命令不能删除只读变量。
tmp="rightNow"
echo "${tmp}"
unset tmp
echo "${tmp}"
unset single
echo "${single}"

# shell自带的变量
echo "$ {0}means:file name is:${0}"
echo "$ {1}means:first param is:${1}"
echo "$ {2}means:second param is:${2}"
echo "$ {#}means:params' number is:${#}"
echo "$ {*}means:all params is : ${*}"
echo "$ {$} means process id is : ${$}"
echo "'$ {@}' means the same output like $\{*\},不过$\*是作为一个参数输出,这里是作为多个参数输出 :${@}"
echo "$\{?\} means the last sript's return is : ${?}"

# $*的结果是一个参数
for i in "$*";
do
    echo "${i}"
done

# $@的结果是多个参数
for i in "$@";
do
    echo "${i}"
done

# 数组, 要用空格分隔数组内元素
my_array=("a" "b" "c" "d")
for i in ${my_array};
do
    echo ${i}
done
echo "${my_array[1]}"
# 不用数组而是用* @可以输出数组所有内容
echo "${my_array[*]}"
echo "${my_array[@]}"

# 下面是获取数组长度的方法
echo "${#my_array[*]}"
echo "${#my_array[@]}"

# 数字计算【方法1:用expr、let等】
var_expr=expr 2 + 2
echo "2+2=${var_expr}"

a=1
b=2
let var_let=${a}+${b}+3
echo "${var_let}"
let var_let=${var_let}+1
echo "${var_let}"

# 方法2:使用declare
declare -i var_declare=1+2
echo "declare计算结果:${var_declare}"

# 方法3:一般用$(( ))的方法;
a=$(( 1+1 ))
echo "${a}"

# 比较数字大小
# -eq -ne -lt -gt -le -ge
a=200
b=200
if [ ${a} -eq ${b} ]
then
    echo "${a} = ${b}"
fi
a=100
if [ ${a} -lt ${b} ]
then
    echo "${a} < ${b}"
fi

# 布尔运算:!:非 -o:或 -a 与
a=0
b=100
c=200
if [ !${a} -a ${b} == 100 -a 100 -lt ${c} ]
then
    echo "OK"
fi

# 逻辑运算
if [[ ${b} == 100 && ${b} -lt ${c} ]]
then
    echo "OK"
fi
# 两种运算方式的区别
# 语法区别
# 从上述举例中可以看出使用逻辑运算符需要加上[[双大括号]],布尔运算符只需要[单大括号]。
# 功能区别
# 逻辑运算符具有特殊的短路功能,可以利用短路特性来实现使用命令1的执行结果(执行shell命令后会得到一个状态码)控制命令2是否执行的效果。

# 字符串运算
# 包含 = != -z -n
a="abc"
b="ccc"
c=${a}
if [ ${a} = ${c} ]
then
    echo "a=c"
else
    echo "a!=c"
fi
if [ -n ${a} ]
then echo "None"
fi

# 文件测试运算符
## -b:检测是否为块设备
## -c:检测是否是字符设备
# -d:检测是否是目录
# -f:检测是否是文件
## -g:检测是否设置了SGIG
## -k:检测是否设置了stick bit
## -p:检测文件是否有名管道
# -r:检测文件是否可读
# -w:检测文件是否可写
# -x:检测文件是否可执行
# -s:检测文件是否为空,非空时返回true
# -e:检测文件(包括)目录是否存在,存在返回true
## -L:检查文件是否存在且为一个符号链接

# 判断并创建一个目录和文件
dir="/temp/tmp/"
file="test"
if [ ! -d "${dir}" ]
then
    echo "${dir}目前不存在,新建它,且不给任何权限。"
    mkdir -p "${dir}"
    chmod -R 000 $(dirname ${dir})
fi
if [ ! -f "${dir}${file}" ]
then
    echo "${dir}${file}不存在,新建一个,且不给任何权限"
    touch "${dir}${file}"
    chmod 444 ${dir}${file}
fi

absFile=${dir}${file}
if [ -r ${absFile} ] # 因为是用root执行。所以权限判断都为true
then
    echo "in"
    chmod 777 ${absFile}
fi

echo "$(ls -l ${absFile})"

# shell中的if else用的是elif
a="abc"
if [ -z ${a} ]
then
    echo "${a}为空。"
elif [ ${a} = "abc" ]
then 
    echo "a=abc"
fi

# 使for输出数字串的几种方法
# 双括号
for((i=1;i<=10;i++));
do
    echo ${i}
done
echo "----------------------------------------"

for i in $(seq 1 2 10)
do
    echo ${i}
done

echo "----------------------------------------"
for i in {1..10}
do
    echo ${i}
done

echo "----------------------------------------"
awk 'BEGIN{for(i=1;i<=10;i++) print i}'

for str in "this is is a string"
do 
    echo "${str}"
done

# while可用于读取键盘信息
echo -n '输入喜欢的食物:'
while read xFILM
do
    echo "我猜你最喜欢的食物是:${xFILM}"
    echo "按下<ctrl+D>退出"
done

# 读文件
tmp=1
while read line
do
    echo "${line}"
    if [ ${tmp} -eq 10 ]
    then
        break
    fi
    let tmp=tmp+1
done < order_header_file.txt

# until循环[一直循环,直到条件满足]
a=1
until [ ${a} -gt 10 ]
do 
    echo ${a}
    (( a++ ))
done

# case...esac选择语句
while true
do
echo -n "输入1~10之间的数字:"
read aNum
case ${aNum} in
    1) echo "你选择了1"
        ;;
    2|3|4) echo "你在2,3,4里面选择了一个"
        ;;
    5|6) echo "你在5,6,里面选择了一个"
        break
        ;;
    *) echo "你选择的数字没在1,2,3,4,5,6中"
        ;;
esac
done

# 补充:重定向概念
# n > file  将文件描述符为 n 的文件重定向到 file。
# n >> file 将文件描述符为 n 的文件以追加的方式重定向到 file。
# n >& m    将输出文件 m 和 n 合并。
# n <& m 将输入文件 m 和 n 合并。
# << tag  将开始标记 tag 和结束标记 tag 之间的内容作为输入。

# 一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:

# 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
# 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
# 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。
# command 2>file
# command 2>>file
# command > file 2>&1
# command >> file 2>&1
最后修改日期: 2024年8月17日

作者

留言

撰写回覆或留言