Shell脚本基础教程

在这里插入图片描述

Shell脚本基础教程

Shell参数定义

定义变量

想要定义变量,只需要使用如下命令即可。

variable_name=variable_value

variable_name表示变量名,variable_value表示变量值。注意,等号与变量名和变量值之间不能有空格

变量名的命名需要遵循如下规则:

  1. 变量名的组成只能是英文字母、数字和下划线
  2. 首字母只能是英文字母和下划线,不能是数字

正确示例:

test="test"
_test=123

错误示例:

1test="test"
test%test=123
test = "test"

使用变量

定义了变量,就要使用变量。使用变量的时候,需要在变量名称前加上符号$

# 定义变量
test="hello world"

# echo是用于字符串输出的命令,这里将变量test输出到控制台
echo $test
echo ${test}!
# 输出结果
hello world
hello world!

由上面的示例,我们看到了变量名外面的花括号是可选的,加花括号是为了帮助识别变量的边界。

推荐给所有变量加上花括号,这是个好的编程习惯。

修改变量

定义的变量是可以修改的,再设置变量的值即可。

# 设置变量test的值为hello world,并打印
test="hello world"
echo ${test}

# 修改变量test的值为hello shell,并打印
test="hello shell"
echo ${test}
# 输出结果
hello world
hello shell

只读变量

使用readonly命令可以将变量定义为只读变量,只读变量的值不能被改变。

# 定义一个变量test
test="222"

# 设置test变量为只读
readonly test

# 修改test变量值为111,修改失败
test="111"
# 输出
test: readonly variable

提示信息告诉,test变量是一个只读的变量,不允许修改。

删除变量

使用unset命令可以删除变量。

# 定一个一个变量test,并打印
test="222"
echo "test的值为:$test"

# 删除变量test,再打印,发现没有了
unset test
echo "test的值为:$test"
# 输出
test的值为:222
test的值为:

刚才我们说使用readonly命令可以将变量定义为只读变量,那只读变量是否允许删除呢?

# 定一个一个变量test,并打印
test="222"
echo "test的值为:$test"

# 设置变量test为只读
readonly test

# 删除变量test,再打印,发现还有,说明没有删除成功
unset test
echo "test的值为:$test"
# 输出
test的值为:222
./test.sh: line 6: unset: test: cannot unset: readonly variable
test的值为:222

根据输出,我们发现了,只读变量是不允许删除的

变量的作用域

变量的作用域也就是变量可以使用的范围。根据变量的作用域,可以将变量分为三种。

  • 局部变量
  • 全局变量
  • 环境变量

局部变量

有的变量只能在函数内部使用,这叫做局部变量。

为了演示局部变量,使用了Shell函数的概念,若不清楚,可点击跳转先学习下函数。

# 定义了一个名为hello的函数
function hello()
{
        local name="Shell"
        echo "函数内获取:$name"
}

# 调用hello函数
hello

echo "函数外获取变量:$name"
# 输出
$ sh variables-scope.sh
函数内获取:Shell
函数外获取变量:

通过输出我们可以看到,使用了local定义的变量成为了局部变量,在函数内可以获取到此变量,但是在函数外获取不到这个变量。

全局变量

全局变量是指在当前的整个Shell进程中都有效的变量。每个Shell进程都有自己的作用域,彼此之间互不影响。在Shell脚本中定义的变量,默认就是全局变量。

#!/bin/bash

# 在脚本中定义了一个变量name,这个变量默认就是全局变量,在整个shell脚本中都可以访问
name="shell"

# 函数内获取变量
function printName()
{
        echo "函数内获取名字为:$name"
}

# 函数外获取变量
echo "函数外获取姓名为:$name"
printName
# 输出
$ sh variables.sh
函数外获取姓名为:shell
函数内获取名字为:shell

由此可以知道,当我们直接定义一个变量的时候,默认是全局变量,整个shell脚本中都可以访问。

环境变量

全局变量只在当前 Shell 进程中有效,对其它 Shell 进程和子进程都无效。我们可以使用export命令,将变量转变为环境变量,这样Shell子进程中就可以访问到Shell父进程的变量了。当然两个没有父子关系的 Shell 进程是不能传递环境变量的。

# 以下操作在命令行中直接进行,才可以看到输出结果
name="shell"
echo "父进行中访问姓名为:$name"

bash
echo "子进程中访问姓名为:$name"

exit

export name
bash
echo "子进程中访问姓名为:$name"

age=20
echo "子进程中访问年龄为:$age"
export age
exit

echo "父进程中访问年龄为:$age"
# 输出
父进行中访问姓名为:shell
子进程中访问姓名为:
子进程中访问姓名为:shell
子进程中访问年龄为:20
父进程中访问年龄为:

由输出结果可以看出,使用export命令之后,子进程中已经可以获取到name变量了。但是子进程export的变量,父进程也是访问不到的。

变量的类型

字符串

字符串是shell编程中最常用最有用的数据类型。字符串可以用单引号,也可以用双引号,也可以不用引号。

  • 单引号:任何字符都会原样输出,单引号字符串中的变量是无效的
  • 双引号:双引号里可以有变量,双引号里可以出现转义字符

字符串还有一些常用的操作,请继续学习。

获取字符串长度
# 定义一个字符串变量,并输出字符串的长度
str="Hello World!"
echo 字符串的长度为:${#str}
# 输出
字符串的长度为:12

我们知道${variable_name}便是使用一个变量,由上面的例子,我们知道了,在变量名之前,加上#符号即${#variable_name},便可获取字符串变量的长度。

获取子字符串
str="Hello World!"
echo 位置1之后的5位字符串为:${str:0:5}
# 输出
位置1之后的5位字符串为:Hello

${variable_name:index:length}在变量名后加上子字符串开始的位置以及长度,即可获取子字符串。这里需要注意的是,索引位置是以0开始,所以index为0表示第一个字符。

查找子字符串位置
str="Hello World!"
echo o字符在字符${str}上的位置为:`expr index "${str}" o`
# 输出
o字符在字符Hello World!上的位置为:5

括住expr index "${str}" o的是反引号,表示要执行里面的内容,这里需要注意。

这里使用了expr命令来取得子字符串的位置。expr index $string $substring表示要在字符串string中找到字符串substring的位置。

更多expr命令的用法读者可以继续深入了解。

数组

定义数组

想要定义数组,可以用括号来表示数组,数组元素用"空格"符号分割。

array_name=(value0 value1 value2 value3)

或者

array_name=(
value0
value1
value2
value3
)
读取数组内元素

想要读取数组,可以使用如下命令:

# 获取数组array_name的索引index的元素
${array_name[index]}

# 获取数组array_name的索引index的元素,并赋值给value
value=${array_name[index]}

# 获取数组中的所有元素
${array_name[@]}

使用示例如下:

arr=("张三" "李四" "王五")

value=${arr[0]}
echo $value
# 输出
张三
获取数组长度

获取数组长度的方法与获取字符串长度的方法类似。

${#array_name[@]}

Shell注释

单行注释

#开头的行就是注释。就像下面这样:

#--------------------------------------------
# 这是一行注释
#--------------------------------------------

多行注释

:<<EOF开头,EOF结尾的便是多行注释。其中EOF可以替换成其他的字符,下面是两个多行注释的例子

:<<EOF
第一行注释
第二行注释
第三行注释
EOF

:<<HAHA
第一行注释
第二行注释
第三行注释
HAHA

Shell流程控制

分支语句

if else语句

if语句的语法如下:

if condition
then
    command1 
    command2
    ...
    commandN 
fi

也可以写成一行,关键点在于使用分号;作为语句的分割

if condition; then command; fi

意思是:如果condition语句成立,则执行then之后的语句,直到出现fi

使用示例演示下if语句的使用。

# 使用test命令判断脚本输入第一个参数和第二个参数的字符是否相等
if test $1 = $2
then
        echo "相等"
fi

if test $1 != $2
then
        echo "不相等"
fi
$ sh test.sh aaa aaa
相等

$ sh test.sh aaa zzz
不相等
# 将if语句写成一行
$ if test 1 -eq 1;then echo "相等";fi
相等

if else 语法`格式:

if condition
then
    command1 
    command2
    ...
    commandN
else
    command
fi

意思是:如果condition语句成立,则执行then之后的语句。若是不成立,则执行else之后的语句,直到出现fi

使用示例演示如下所示:

# 使用test命令判断脚本输入第一个参数指定的文件是否存在
if test -e $1
then
        echo "文件存在"
else
        echo "文件不存在"
fi
# 输出
$ sh test.sh "test.sh"
文件存在

$ sh test.sh "test.sh1"
文件不存在

if else-if else 语法格式:

if condition1
then
    command1
elif condition2 
then 
    command2
else
    commandN
fi

意思是:如果condition1语句成立,则执行then之后的语句。若是不成立,则继续判断condition2是否成立,若成立,则执行then之后的语句。若还是不成立,则执行else之后的语句,直到出现fi

使用示例演示如下所示:

# 使用test命令判断脚本输入第一个参数和第二个参数的大小比较
if test $1 -eq $2
then
        echo "数值相等"
elif test $1 -gt $2
then
        echo "$1大于$2"
else
        echo "${1}小于${2}"
fi
# 输出
$ sh test.sh 10 10
数值相等

$ sh test.sh 10 11
10小于11

$ sh test.sh 12 11
12大于11

case语句

case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。

case语句格式如下:

casein
模式1)
    command1
    command2
    ...
    commandN
    ;;
模式2)
    command1
    command2
    ...
    commandN
    ;;
esac

模式取值可以为变量或常数,每一模式必须以右括号结束。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;

取值将检测匹配的每一个模式。

一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令。

循环语句

for循环

for循环语句格式为:

for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done

也可以写成一行

for var in item1 item2 ... itemN; do command1; command2… done;

示例如下:

for value in 1 2 3 4 5
do
    echo "The value is: $value"
done
# 输出
The value is: 1
The value is: 2
The value is: 3
The value is: 4
The value is: 5

while循环

while循环的语句格式如下:

while condition
do
    command
done

condition语句判断为true时,执行command语句;执行结束之后,继续判断condition语句,直到为false,结束执行。

示例如下:

value=1
while(( $value<=5 ))
do
    echo 值为:$value
    let "value++"
done
# 输出
值为:1
值为:2
值为:3
值为:4
值为:5

跳出循环

在循环的过程中,经常需要做出跳出循环的操作。这里又包含了两种情况,一种是跳出当前循环,进入下一次循环;另一种是,直接跳出循环语句,执行循环语句后面的代码。

第一种,跳出当前循环,进入下一次循环,使用continue命令。

第二种,跳出循环,使用break命令。

Shell函数

定义函数

可以在Shell脚本内定义函数。格式如下所示:

[ function ] functioName [()]

{

    action;

    [return int;]

}
  1. function关键字是可选的,可以设置,也可以不设置。

若对这个格式不是很理解,我们接下来就详细来说明。

我们先来尝试简单地使用函数。我们先定义一个函数,然后再调用它。如下所示:

# 定义一个函数,名为getName,其作用为打印字符串Shell
function getName(){
  echo "Shell"
}

# 调用函数getName
getName
# 输出
Shell

调用函数

直接使用函数名称即可调用函数。

在函数名称后面,再带上一些参数,便是调用函数并给函数传递了一些参数。

# 定义一个函数getName
function getName(){
  echo "Shell"
}

# 直接使用函数名调用函数
getName

# 定义一个函数hello
function hello(){
  echo "Hello $1"
}

# 直接使用函数名调用函数,并传递了一个字符串作为参数
hello "孙悟空"
# 输出
Shell
Hello 孙悟空

函数参数

函数是支持传递参数的,在函数体内部,通过$n的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数,以此类推。注意,$10不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。

# 定义一个函数hello
function hello(){
  echo "Hello $1"
}

# 直接使用函数名调用函数,并传递了一个字符串作为参数
hello "孙悟空"
# 输出
Hello 孙悟空

另外,还有几个特殊字符用来处理参数:

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

函数返回值

函数的返回值,可以显式使用关键字return返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值,可选值为0-255

return表示退出函数并返回一个退出值,脚本中可以在调用函数后,用$?获取到该退出值。

# 定义了一个函数sum,read命令用于在执行中输入数字,并设置到参数firstNum和secondNum
function sum(){
    echo "这个函数会对输入的两个数字进行相加运算..."
    echo "输入第一个数字: "
    read firstNum
    echo "输入第二个数字: "
    read secondNum
    echo "两个数字分别为 $firstNum$secondNum"
    return $(($firstNum+$secondNum))
}

# 运行函数sum,并通过$?获取到函数的返回值进行打印
sum
echo "输入的两个数字之和为$?"
# 输出
这个函数会对输入的两个数字进行相加运算...
输入第一个数字:
1
输入第二个数字:
2
两个数字分别为 12
输入的两个数字之和为3

函数返回值在调用该函数后通过$?来获得。

递归调用函数

什么叫做递归调用,便是函数自己调用自己。

函数库

一些注意事项

  1. 所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。
  2. Shell函数中定义的变量默认也是全局变量,它和在函数外部定义变量拥有一样的效果。

常见的命令

echo

echo命令用于字符串的输出。命令格式:

echo string

printf

printf也是一个输出命令,但是可以格式化字符串。命令格式:

printf  format-string  [arguments...]

test命令

Shell中的test命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。

数值测试

参数说明
-eq等于则为真
-ne不等于则为真
-gt大于则为真
-ge大于等于则为真
-lt小于则为真
-le小于等于则为真
# 使用test命令判断脚本输入第一个参数和第二个参数的大小比较
if test $1 -eq $2
then
        echo "数值相等"
elif test $1 -gt $2
then
        echo "$1大于$2"
else
        echo "${1}小于${2}"
fi
# 输出
$ sh test.sh 10 10
数值相等

$ sh test.sh 10 11
10小于11

$ sh test.sh 12 11
12大于11

字符串测试

参数说明
=等于则为真
!=不相等则为真
-z 字符串字符串的长度为零则为真
-n 字符串字符串的长度不为零则为真
# 使用test命令判断脚本输入第一个参数和第二个参数的字符是否相等
if test $1 = $2
then
        echo "相等"
fi

if test $1 != $2
then
        echo "不相等"
fi
$ sh test.sh aaa aaa
相等

$ sh test.sh aaa zzz
不相等

文件测试

参数说明
-e 文件名如果文件存在则为真
-r 文件名如果文件存在且可读则为真
-w 文件名如果文件存在且可写则为真
-x 文件名如果文件存在且可执行则为真
-s 文件名如果文件存在且至少有一个字符则为真
-d 文件名如果文件存在且为目录则为真
-f 文件名如果文件存在且为普通文件则为真
-c 文件名如果文件存在且为字符型特殊文件则为真
-b 文件名如果文件存在且为块特殊文件则为真
# 使用test命令判断脚本输入第一个参数指定的文件是否存在
if test -e $1
then
        echo "文件存在"
else
        echo "文件不存在"
fi
# 输出
$ sh test.sh "test.sh"
文件存在

$ sh test.sh "test.sh1"
文件不存在

其他

Shell中$各种含义

符 号含 义
$0脚本名
$#参数个数
$n传递给脚本的参数值,$1表示第1参数、$2表示第2参数
$?上次退出的状态(返回值),0没有错误,1错误
$*所有参数列表。"$*“时,是”$1 $2 … $n"的形式
$@所有参数列表。“$@“时,是”$1” “ 2 " … " 2" … " 2""n” 的形式
$$当前进程的编号(ProcessID)
$!shell最后运行的后台Process的PID
$var变量,会与后面的连接,如$var_a,会当做变量var_a
${var}变量,界定范围
$()(反引号)类似,里面执行完再返回值,所有shell通用
$[]可进行算术运算和逻辑运算,不支持浮点和字符串
$(())可进行算术运算和逻辑运算,不支持浮点和字符串。里面的变量可以省略$

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/81615.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言入门_Day7 逻辑运算

目录&#xff1a; 前言 1.逻辑运算 2.优先级 3.易错点 4.思维导图 前言 算术运算用来进行数据的计算和处理&#xff1b;比较运算是用来比较不同的数据&#xff0c;进而来决定下一步怎么做&#xff1b;除此以外还有一种运算叫做逻辑运算&#xff0c;它的应用场景也是用来影…

电脑远程接入软件可以进行文件传输吗?快解析内网穿透

电脑远程接入软件的出现&#xff0c;让我们可以在两台电脑之间进行交互和操作。但是&#xff0c;很多人对于这些软件能否进行文件传输还存在一些疑问。下面的文章将解答这个问题。 1.电脑远程接入软件可以进行文件传输。传统上&#xff0c;我们可能会通过传输线或者移动存储设…

Redis在Java中的基本使用

本片将介绍 Redis 在 Java 中的基本使用 文章目录 1、使用jedis操作redis1.1、Jedis简介1.2、引入jedis的Maven依赖1.2、获取连接1.3、使用实例 2、对于JedisPooled的使用2.1、使用JedisPooled2.2、关于连接池 3、SpringBoot下使用Redis3.1、引入Maven依赖3.2、配置Redis连接3.…

RabbitMq:Topic exchange(主题交换机)的理解和使用

RabbitMq:Topic exchange(主题交换机)的理解和使用 在RabbitMq中&#xff0c;生产者的消息都是通过交换机来接收&#xff0c;然后再从交换机分发到不同的队列中去&#xff0c;在分发的过程中交换机类型会影响分发的逻辑&#xff0c;下面主要讲解一下主题交换机。 ​ 主题交换…

pycharm上传项目到github,版本管理

前提&#xff1a;下载git 设置Git路径 登录Github 此时自动打开浏览器&#xff0c;并打开连接页面&#xff0c;点击 Authorize GitHub。登录&#xff1a; 创建本地仓库 提交到Github 填写初始提交相关信息 origin&#xff0c;它们只是远程服务器的一个别名&#xff0c;否则你就…

NPM 创建和管理组织

目录 1、创建一个组织 2、将用户帐户转换为组织 3、组织中开启双因素身份验证 3.1 关于组织的双因素身份验证 3.2 先决条件 3.3 在您的组织中要求双因素身份验证 3.4 帮助已删除的成员和外部协作者重新加入您的组织 4、重命名组织 5、删除组织 1、创建一个组织 任何n…

“Spring管理JavaBean的过程及Bean的生命周期“

目录 引言1.弹簧容器2. Bean的生命周期2.1 配置javaBean2.2. 解析Bean的定义2.3 检查是否需要添加自己的功能2.4 初始化2.5 实现Aware接口2.6 扩展2.7. 销毁 3. 单例模式和原型模式3.1. 单例模式3.2. 原型模式 4. 总结 引言 Spring框架是一个非常流行的Java应用程序框架&#…

【【verilog典型电路设计之流水线结构】】

verilog典型电路设计之流水线结构 下图是一个4位的乘法器结构&#xff0c;用verilog HDL 设计一个两级流水线加法器树4位乘法器 对于流水线结构 其实需要做的是在每级之间增加一个暂存的数据用来存储 我们得到的东西 我们一般来说会通过在每一级之间插入D触发器来保证数据的联…

【AIGC】 快速体验Stable Diffusion

快速体验Stable Diffusion 引言一、安装二、简单使用2.1 一句话文生图2.2 详细文生图 三、进阶使用 引言 stable Diffusion是一款高性能的AI绘画生成工具&#xff0c;相比之前的AI绘画工具&#xff0c;它生成的图像质量更高、运行速度更快&#xff0c;是AI图像生成领域的里程碑…

Linux/Ubuntu 的日常更新,如何操作?

我安装的是Ubuntu 20.04.6 LTS的Windows上Linux子系统版本&#xff0c;启动完成后显示&#xff1a; Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.15.90.4-microsoft-standard-WSL2 x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.c…

Azure不可变Blob存储

文章目录 Azure不可变Blob存储介绍Azure不可变性策略实战演练 Azure不可变Blob存储介绍 不可变的存储是一种用于存储业务关键型 Blob 数据的存储方式。与可变存储相反&#xff0c;不可变存储的特点是一旦数据被写入后&#xff0c;便无法再对其进行修改或删除。这种存储方式提供…

【2023最新爬虫】爬取知乎任意问题下的全部回答

老规矩&#xff0c;先上结果&#xff1a; 爬取了前200多页&#xff0c;每页5条数据&#xff0c;共1000多条回答。&#xff08;程序设置的自动判断结束页&#xff0c;我是手动break的&#xff09; 共爬到13个字段&#xff0c;包含&#xff1a; 问题id,页码,答主昵称,答主性别,…

Ubuntu一直卡死的问题(20.04)

Ubuntu一直卡死的问题&#xff08;18.04&#xff09;_ubuntu频繁死机_Mr.Yi的博客-CSDN博客 我自己的解决方法: 1、首先强制关机重启后&#xff0c;直接打开命令行查看磁盘的使用&#xff1a; df -h发现/dev/loop都沾满了&#xff0c;我们能需要做的就是把他们清理干净 sud…

【模拟集成电路】反馈系统——基础到进阶(二)

【模拟集成电路】反馈系统——基础到进阶&#xff08;二&#xff09; ------------------------------------------------文末附往期文章链接-------------------------------------- 1反馈结构2反馈系统分析2.1环路增益求解方法2.1二端口网络2.2电压-电压反馈2.2.1闭环增益2.2…

ant-design-vue在ios使用AUpload组件唤起了相机,HTML的 `capture` 属性

在使用ant design vue组件的上传组件AUpload的时候有一个问题&#xff0c;直接按照demo写&#xff0c;在ios上会唤起相机&#xff0c;但是实际上我们的需求是弹出选择相册/相机这个弹框。 解决办法是加一个 cupture"null"这个属性即可 <a-upload:capture"nu…

人工智能学习框架—飞桨Paddle人工智能

1.人工智能框架 机器学习的三要素&#xff1a;模型、学习策略、优化算法。 当我们用机器学习来解决一些模式识别任务时&#xff0c;一般的流程包含以下几个步骤&#xff1a; 1.1.浅层学习和深度学习 浅层学习(Shallow Learning)&#xff1a;不涉及特征学习&#xff0c;其特征…

【云原生】【k8s】Kubernetes+EFK构建日志分析安装部署

目录 EFK安装部署 一、环境准备&#xff08;所有主机&#xff09; 1、主机初始化配置 2、配置主机名并绑定hosts&#xff0c;不同主机名称不同 3、主机配置初始化 4、部署docker环境 二、部署kubernetes集群 1、组件介绍 2、配置阿里云yum源 3、安装kubelet kubeadm …

【无线点对点网络时延分析和可视化】模拟无线点对点网络中的延迟以及物理层和数据链路层之间的相互作用(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

34.Netty源码之Netty如何处理网络请求

highlight: arduino-light 通过前面两节源码课程的学习&#xff0c;我们知道 Netty 在服务端启动时会为创建 NioServerSocketChannel&#xff0c;当客户端新连接接入时又会创建 NioSocketChannel&#xff0c;不管是服务端还是客户端 Channel&#xff0c;在创建时都会初始化自己…

【云计算原理及实战】初识云计算

该学习笔记取自《云计算原理及实战》一书&#xff0c;关于具体描述可以查阅原本书籍。 云计算被视为“革命性的计算模型”&#xff0c;因为它通过互联网自由流通使超级计算能力成为可能。 2006年8月&#xff0c;在圣何塞举办的SES&#xff08;捜索引擎战略&#xff09;大会上&a…