shell --- 基础篇

2023-09-20 11:17:47

一、符号介绍

$#脚本的参数个数
$*以一个单字符串显示所有脚本传递的参数
$$当前进程ID号
$!后台运行的最后一个进程的ID号
$@与$*相同,但是使用时加引号,并在引号中返回每个参数。
$-显示Shell使用的当前选项,与set命令功能相同。
$?显示最后命令的退出状态(或函数的返回值)。0表示没有错误

三、基础语法

echo --- 输出

  • 基本格式
echo "<输出信息>"

 变量定义

  • 基本格式
# 私有变量定义 --- 只有当前脚本可以看到
<变量名>=<变量内容>
delcara <变量名>=<变量内容>

#用户环境变量定义
export <变量名>=<变量内容>

#数组定义
<变量名>=(
    "成员1"
    "成员2"
    "..."
)

printf --- 输出

  • 基本格式
printf <格式化字符串> <参数>
格式指示符描述
%b相对应的参数被视为含有要被处理的转义序列之字符串,见表:转义序列
%cASCII 字符
%d, %i十进制数
%e浮点格式
%E浮点格式
%f浮点格式
%g%e或%f转换, 看哪一个较短,则删除结尾的零
%G%E或%f转换, 看哪一个较短,则删除结尾的零
%o不带正负号的八进制值
%s字符串
%u不带正负号的十进制值
%x不带正负号的十六进制值,使用a至f表示10到15
%X不带正负号的十六进制值,使用A至F表示10到15
%%字面意义%
转义序列描述
\a
\b
\c
\f
\n
\r
\t
\v
\\
\ddd
\0ddd

let --- 整数数学运算

  • 基本格式
let <运算表达式>
  • 示例
#!/bin/bash

let count=0

let count++

let a=${count}+1

echo "count=${count} a=${a}"
  • 运行结果 

function --- 函数

返回值为整数

  • 基本格式
# 函数定义
[function] <函数名>() {
    <入参1>=$1
    <入参2>=$2
    <入参n>=$n
    
    <...>
    return <整数返回值>
}

# 函数调用
<函数名> <参数1> <参数2> <...>
<函数返回值>=$?
函数相关符号描述
$*以一个单字符串显示所有参数
$@与$*相同,但是使用时加引号,并在引号中返回每个参数。
$0-$n函数的每一个参数,$0表示可执行程序本身,$1表示第一个参数
$?函数运行结果(返回值)
$#参数个数

注:

不省略关键字 function 时,函数名后面的'()' 可以省略

省略关键字 function 时,函数名后面的'()' 不可以省略

  • 示例
#!/bin/bash

function cal_sum1() {
    echo "cal_sum1 params: $@"
   
    let sum=$1+$2
    return $sum
}

cal_sum2() {
    echo "cal_sum2 params: $*"

    let sum=$1+$2
    return $sum
}

cal_sum1 100 20
echo "sum1 100+20=$?"

cal_sum2 100 110
echo "sum2 100+110=$?"
  • 运行结果

 返回值为字符串

  •  基本格式
# 函数定义
[function] <函数名>() {
    <入参1>=$1
    <入参2>=$2
    <入参n>=$n
    
    <...>
    echo "<字符串>"
}

# 函数调用
<返回值变量>=$(<函数名> <参数1> <参数2> <...>)

注:此处获取到返回值,永远是函数中第一个echo输出的字符串 

  • 示例
#!/bin/bash

function test_func() {
    echo "$1"
    echo "is return val ?"
}

result=$(test_func "hello world")
echo "test_func return val=$result"
  • 运行结果

 函数入参为数组

  • 基本格式
# 函数定义
[function] <函数名>() {
    <数组入参>=$1
    <入参2>=$2
    <入参n>=$n
    
    for <成员变量> in ${数组入参[@]}
    do
        <...>
        echo "element=${成员变量}"
    done
    return <整数返回值>
}

<数组变量名>=(
    "成员1"
    "成员2"
    "..."
)

# 函数调用
<函数名> "${数组变量名[*]}" <参数2> <...>
<函数返回值>=$?
  • 示例 
#!/bin/bash

function test_func() {
    list=$1

    for student in ${list[@]}
    do
        echo ${student}
    done 
}

student_list=(
    "xiaoming"
    "zhangsang"
    "xiaozhang"
)

test_func "${student_list[*]}"
  •  运行结果

 if --- 条件判断

  • 基本格式
if [ <条件表达式> ]; then
    <...>
elif [ <条件表达式> ]; then
    <...>
else
    <...>
fi

整数比较

  • 基本格式
if [ <整数> [选项] <整数> ]; then
    <...>
fi
选项描述
-eq等于
-ne不等于
-gt大于
-ge大于等于
-lt小于
-le小于等于

字符串比较

  • 基本格式
if [ "<字符串1>" [选项] "<字符串1>" ]; then
    <...>
fi
选项描述
== 或 =两个字符串相等
!=两个字符串不相等
<字符串1 字典排序在 字符串2前面
>字符串1 字典排序在 字符串2后面

 字符串判断

  • 基本格式
if [ [选项] "<字符串>" ]; then
    <...>
fi
选项描述
-n字符串长度非0,则为真, 也即字符串不为空。-n 可缺省
-z字符串长度为0,则为真, 也即字符串为空。-z 不可缺省

文件判断

  • 基本格式
if [ [选项] <文件或目录> ]; then
    <...>
fi
选项描述
-a文件存在则为真
-d文件为目录且存在为真
-e文件或目录存在时为真
-f文件存在且为一个普通文件则为真
-r文件存在且具有可读权限则为真
-w文件存在且具有可写权限则为真
-x文件存在且具有可执行权限则为真
-b文件存在且是一个块文件则为真
-c文件存在且是一个字符文件则为真
-g文件存在且设置了SGID则为真
-h文件存在且是一个符号符号链接文件则返回为真
-k文件存在且已经设置了冒险位则返回为真
-p文件存并且是命令管道时返回为真
-s文件存在且大小非0时为真则返回为真
-u文件存在且设置了SUID位时返回为真
-O文件存在且属有效用户ID则返回为真
-G文件存在且默认组为当前组则返回为真
-L文件存在且是一个符号连接则返回为真
-N文件存在 and has been mod如果ied since it was last read则返回为真
-S文件存在且是一个套接字则返回为真

文件比较

  • 基本格式
if [ <文件1> [选项] <文件2> ]; then
    <...>
fi
选项描述
-nt如果 文件1 比 文件2 新, 或者 文件1 存在但是 文件2 不存在则返回为真
-ot如果 文件1 比 文件2 老, 或者 文件2 存在但是 文件1 不存在则返回为真
-ef如果 文件1 和 文件2 指向相同的设备和节点号则返回为真

逻辑判断

  • 逻辑非
if [ ! <表达式> ]; then
    <...>
fi
  • 逻辑与 
if [ <表达式> -a <表达式> ]; then
    <...>
fi

if [ <表达式> ] && [ <表达式> ]; then
    <...>
fi
  • 逻辑或 
if [ <表达式> -a <表达式> ]; then
    <...>
fi

if [ <表达式> ] || [ <表达式> ]; then
    <...>
fi

高级特性

数学表达式 --- (())

# 双圆括号(( )):表示数学表达式
# 在判断命令中只允许在比较中进行简单的算术操作,而双圆括号提供更多的数学符号,
# 而且在双圆括号里面的'>','<'号不需要转意。

if (( <数字> [运算符] <数字> ))
运算符含义
>大于
>=大于等于
<小于
<=小于等于
==等于
!=不等于

高级字符串处理 --- [[]]

# 双方括号[[ ]]:表示高级字符串处理函数
# 双方括号中判断命令使用标准的字符串比较,还可以使用匹配模式,
# 从而定义与字符串相匹配的正则表达式。

if [[ <字符串> [运算符] <字符串> [逻辑运算符] <字符串> [运算符] <字符串> ]]

if [[ [运算符] <文件或目录> [逻辑运算符] [运算符] <文件或目录> ]]
运算符含义
=两个字符串相等
!=两个字符串不相等
-n字符串长度非0,则为真, 也即字符串不为空。-n 可缺省
-z字符串长度为0,则为真, 也即字符串为空。-z 不可缺省
-r文件存在且具有可读权限则为真
-l文件存在且是一个符号连接则返回为真
-w文件存在且具有可写权限则为真
-x文件存在且具有可执行权限则为真
-f文件存在且为一个普通文件则为真
-d文件为目录且存在为真
-s文件存在且大小非0时为真则返回为真
-nt如果 文件1 比 文件2 新, 或者 文件1 存在但是 文件2 不存在则返回为真
-ot如果 文件1 比 文件2 老, 或者 文件2 存在但是 文件1 不存在则返回为真
逻辑非
&&逻辑与
||逻辑或

for --- 循环

  • 基本格式
<数组名>=(
    <"...">
)
for <变量> in ${<数组名>[@]}
do
    if [ <表达式> ]; then
        <...>
        continue
    fi

    <...>
    break
done

   或

for ((<赋值表达式>; <条件表达式>; <循环表达式>))  
do  
    if [ <表达式> ]; then
        <...>
        continue
    fi

    <...>
    break
done
  • 示例
array=(
    "xiaoming"
    "zhangsan"
)
for i in ${array[@]}
do
    echo $i
done

for (( i=1; i<3; i++ ))
do
    echo $i
done
  • 运行结果 

 

while --- 循环

  • 基本格式
while [ <表达式> ];  
do  
    if [ <表达式> ]; then
        <...>
        continue
    fi

    <...>
    break
done

  或

while [[ <表达式> ]];  
do  
    if [ <表达式> ]; then
        <...>
        continue
    fi

    <...>
    break
done
  •  示例
#!/bin/bash

let count=0

while [[ $count -le 5 ]];
do
    echo $count
    ((count++))
done
  •  运行结果

until --- 表达式条件取反循环

  • 基本格式
until [ <表达式> ];  
do  
    if [ <表达式> ]; then
        <...>
        continue
    fi

    <...>
    break
done

   或

until [[ <表达式> ]];  
do  
    if [ <表达式> ]; then
        <...>
        continue
    fi

    <...>
    break
done
  • 示例 
#!/bin/bash

let count=8

until [[ $count -le 5 ]];
do
    echo $count
    ((count--))
done
  •  运行结果

case --- 分支

  • 基本格式
case $<变量> in
    <选项>)
        <...>
        break
        ;;
    <...>)
        <...>
        break
        ;;
    *)
        <...>
        break
esac

select --- 选择

  • 基本格式
<选项列表名>=(
    <"选项">
    <...>
)
PS3="提示信息:"
select <变量> in ${<选项列表名>[@]}; 
do 
    <...>
    break; 
done
  • 示例 
// select和case结合

select_list=(
    "xiaoming"
    "xiaozhang"
)
PS3="Please select a student:"
select args in ${select_list[@]}
do
    case $args in
        "xiaoming")
            echo "student is xiaoming"
            break
            ;;
        "xiaozhang")
            echo "student is xiaozhang"
            break
            ;;
        *)
           break
    esac
done
  • 运行结果

四、常用命令介绍

 read --- 读取

  • 基本格式
read [选项] <输入>
选项说明
-a限定输入为数组
-d <结束符号>指定结束符,遇到该字符是立即结束
-e 使用readline处理输入,允许使用和命令行相同的方式编辑输入
-i <文本>如果用户直接按Enter键,使用文本作为默认值,需要配合-e选项使用
-n <num>从输入中读取num个字符,而非读取一整行
-N <num>只在准确读取num个字符后返回,除非遇到EOF或读取超时,忽略任何分隔符。
-p <"提示信息:">     指定输出提示信息
-r反斜杠转义不会生效,意味着行末的’\’成为有效的字符,例如使 \n 成为有效字符而不是换行
-s不显示输入的值,一般用于密码
-t <timeout>指定超时时间,单位:秒
-u fd从文件描述符fd中读取输入

从标准输入读取内容

  • 基本格式
read -p <"提示信息"> <变量>
  •  示例
#!/bin/bash

read -p "请输入:" input

echo $input
  • 运行结果

读取文件内容

while 循环法

  • 基本格式
while read [选项] <变量>
do
    # 默认每次从文件中读取一整行,也可以通过read支持的选项改变默认行为
    <...>
done < <文件>

文件描述符法

  • 基本格式
Exec 3<&0         # 将所有内容重定向到文件描述符3来关闭文件描述0
Exec 0<<文件>     # 将输入文件放到文件描述符0
while read [选项] <变量>
do
    # 默认每次从文件中读取一整行,也可以通过read支持的选项改变默认行为
    <...>
done

更多推荐

IntelliJ IDEA下基于Scala实现的Git检查工具

本文使用Scala实现自定义的Git检查工具,读者可以基于本文的示例进行扩展与实现,也可以进行其他应用方向的尝试。01、Git检查工具在实现Git检查工具之前需要知道程序究竟要做什么。我们知道,在管理Git分支时可以进行代码合并操作,这样可以将其他开发者提交的内容同步到当前分支中,当用户对自己的分支进行提交时就不会与现

深入理解 Java 异步编程:Future 和 CompletableFuture 的全面比较

深入理解Java异步编程:Future和CompletableFuture的全面比较FutureCompletableFuture选择适合的场景和需求:理解Future和CompletableFuture的底层实现、用法以及它们的优劣势对深入了解这两个概念非常重要。我将从底层开始,详细解释它们,然后根据不同场景和需求讨

评价模型:层次分析法

写在前面:博主本人大学期间参加数学建模竞赛十多余次,获奖等级均在二等奖以上。为了让更多学生在数学建模这条路上少走弯路,故将数学建模常用数学模型算法汇聚于此专栏,希望能够对要参加数学建模比赛的同学们有所帮助。目录1.模型建立1.1建立层次结构模型1.2构造判断矩阵1.3判断矩阵的一致性检验1.4层次总排序及一致性检验2.

Java学习笔记40——Lambda表达式

Lambda表达式Lambda表达式函数式编程思想概述Lambda表达式的标准格式Lambda表达式练习练习1练习2练习3Lambda表达式的省略模式Lambda表达式的注意事项Lambda表达式与接口的区别Lambda表达式函数式编程思想概述面向对象思想强调“必须通过对象的形式做事”在函数式思想中尽量忽略面向对象的复

DipC 构建基因组 3D 结构(学习笔记)

背景本文主要记录了DipC数据的复现过程、学习笔记及注意事项。目录下载SRA数据使用SRAToolkit转换SRA数据为Fastq格式使用bwa比对测序数据使用Hickit计算样本的基因组3D结构使用散点图展示3D结构计算3D结构重复模拟的稳定性其他步骤1.下载SRA数据1.1从NCBI网站下载SRA数据(桌面操作)根

考研英语笔记:好难

文/谷雨不用再去深圳出差了,在公司混日子,备考时间增加了许多。除去数学和专业课,我现在花费在英语上的时间不算多,每天研究一篇经济学人的精读,然后做些习题。今天我看的是8.26期经济学人的一篇文章《AIcouldfortifybigbusiness,notupendit》。fortify本意是筑防御工事以防卫;(尤指)筑

极光笔记 | 极光服务的信创改造实践

什么是信创?信创全称为“信息技术应用创新”,主要包含应用于通信、云计算、大数据、人工智能、工业互联网等诸多高新产业的基础技术。基础技术则包含基础硬件、基础软件、应用软件、信息安全四大板块。其中:基础硬件主要包括:芯片、服务器/PC、存储等;基础软件包括:数据库、操作系统、中间件等;应用软件包括:办公软件、ERP和其它软

python 全网最优雅命令行参数解析, 没有之一

背景我们在编写python程序时,程序中经常会提供多种功能或者模式,在实际使用时根据不同的参数使用不同的功能。那么如何获取命令行传入进来的参数呢?一般方法一般情况下,我们会使用sys模块,如👇importsys#打印sys模块获取到的命令行参数print(sys.argv)或者,我们会使用getopt模块,如👇im

金融和大模型的“两层皮”问题

几年前,我采访一位产业专家,他提到了一个高科技到产业落地的主要困惑:两层皮。一些特别牛的技术成果在论文上发表了,这是一层皮。企业的技术人员,将这些成果产品化、商品化的时候,可能出于工程化的原因,会做一些简化,这是另一层皮。两层皮之间,是有gap的,就像卖家秀和买家秀一样,并不是融合且一致的。而往往是那些有技术人才、研发

C2基础设施威胁情报对抗策略

威胁情报是指在信息安全和安全防御领域,收集、分析和解释与潜在威胁相关的信息,以便预先发现并评估可能对组织资产造成损害的潜在威胁,是一种多维度、综合性的方法,其通过信息的收集、分析和研判,帮助组织了解可能对其安全构成威胁的因素。这种方法不仅仅着重于技术层面,还包括了社会、心理、政治等多个维度,以此更好地应对不断变化和复杂

基于SSM的旅游网站系统

基于SSM的旅游网站系统【附源码文档】、前后端分离开发语言:Java数据库:MySQL技术:Spring+SpringMVC+MyBatis+Vue工具:IDEA/Ecilpse、Navicat、Maven【主要功能】角色:管理员、用户管理员:用户管理、景点信息管理、购票信息管理、酒店信息管理、客房类型管理、客房信息管

热文推荐