首页 > 系统相关 >Shell 编程基础

Shell 编程基础

时间:2022-12-27 10:07:03浏览次数:37  
标签:wan Shell day2 编程 基础 echo sh root localhost


一、Shell入门基础

1.Shell 脚本的执行

(1)以相对路径的方式:

[root@wan day1]#vim +  haha.sh
[root@wan day1]#chmod +x haha.sh
[root@wan day1]#./haha.sh

(2)以绝对路径的方式执行:

[root@wan ~]# /shell/day1/haha.sh

注:以上两种方法执行时,该脚本必须拥有可执行的权限,否则会出现报错

(3)指定解释器执行脚本

[root@wan ~]# sh /shell/day1/haha.sh 
[root@wan ~]# bash /shell/day1/haha.sh
[root@wan day1]# sh haha.sh
[root@wan day1]# bash haha.sh

(4)在当前shell环境中执行:

[root@wan day1]# source /shell/day1/haha.sh
[root@wan day1]# . /shell/day1/haha.sh
[root@wan day1]# source haha.sh
[root@wan day1]# . haha.sh

注:前三种执行,会开启子shell执行脚本,最后一种,会在当前shell中执行脚本(会改变当前用户的所在目录)

2.echo 的使用

(1)标准输出:

[root@wan day1]# echo hello

(2)输出并不换行:

[root@wan day1]# echo -n hello

(3)输出启用反写线转义:

[root@wan ~]# echo -e "name:\twan"
(4)输出带颜色的内容:

格式:

echo -e "\033 [字体控制选项;字背景颜色;文字颜色m字符串1033 [0m"
常见的字体颜色:重置=0, 黑色=30,红色=31,绿色=32,黄色=33,蓝色=34,紫色=35,天蓝色=36,白色=37。
常见的背景颜色:重置=0, 黑色=40,红色=41, 绿色=42,黄色=43,蓝色=44, 紫色=45,天蓝色=46,白色=47。
字体控制选项: 1表示高亮,4表示下划线,5表示闪烁等。

例如:

[root@wan ~]# echo -e "\033[4;41;36m something here \033[0m"

(5)显示变量内容:

echo $变量名
[root@wan ~]# echo $USER

(6)引用一个命令执行的结果:

[root@wan ~]# echo `whoami`
[root@wan ~]# echo $(whoami)

实例:编写一个脚本,显示当前系统时间、当前系统用户:

echo "当前系统时间是:$(date +'%F %T')"
echo "当前用户:$(whoami)"

3.printf 的使用

[root@wan day1]# printf "%s\n" $USER
[root@wan day1]# printf "%i\n" 266
[root@wan day1]# printf "%2.3f\n" 3.141592

4.history 的使用

history -w  //将历史命令写入缓存文件  .bash_history
[root@wan ~]# history -c //清除历史命令

5.输入与输出重定向

(1)输入重定向: <

1)输出结果作为标准输入:

[root@wan ~]# wc -l < /etc/passwd

2)从文件输入内容:

cat < /etc/passwd

示例:快速生成文件:

# cat > user.lst << EOF
> tom
> bob
> john
> EOF

(2)输出重定向: >

1)标准输出重定向:

[root@wan ~]# help > 1.txt   //以覆盖的方式将正确命令输出到指定文件
[root@wan ~]# cd >> 1.txt //以追加的方式将正确命令输出到指定文件

2)标准错误输出重定向:

[root@wan ~]# ipconfig 2> 2.txt   //以覆盖的方式将错误命令输出到指定文件
[root@wan ~]# ipconfig 2>> 2.txt //以追加的方式将错误命令输出到指定文件

3)将正确和错误的追加输出到同一文件

[root@wan ~]# (ls;lllls) >  3.txt  2>&1   //以覆盖的方式将错误和正确的命令输出到同一文件
[root@wan ~]# (mv;pwc) > 3.txt 2>&1 //以追加的方式将错误和正确的命令输出到同一文件
[root@wan ~]# (ifconfig;dydy) &> 5.txt   //以覆盖的方式将错误和正确命令输出到指定文件
[root@wan ~]# (ifconfig:dydy) &>> 5.txt //以追加的方式将错误和正确命令输出到指定文件

4)将正确和错误的追加输出到不同文件

[root@wan ~]# (ls;vy) >> 6.txt 2>>7.txt  //以追加的方式将错误和正确命令输出到不同文件

6.命令执行顺序

(1)按命令顺序依次执行: ;

[root@wan ~]# date;ls;lalalala;pwd

(2)若前面的命令没有执行成功,则不执行后面的命令 : &&

[root@wan ~]# date && ls && lalalala &&pwd

(3)前面执行成功后面不执行,否则反之: ||

[root@wan ~]# ls || pwd
[root@wan ~]# lslsls | pwd

7.管道符的使用:

提取系统网卡的IP地址:

[root@wan ~]# ip a | grep ens33 | grep inet | cut -d /  -f1 | tr -s ' ' | cut -d' ' -f3

注:tr -s :讲多个空格压缩为一个空格

备份文件

cp  /etc/httpd/conf/httpd.conf{,http_bak}

二、变量

1.变量的命名

变量命名使用数字、字母、下划线,且数字不能打头;尽可能见名知意

2.变量的定义

变量名=变量值

注:“=“ 两边不能有空格;定义字符串类型,字符串中间有空格,需要给字符加上引号

my_name=zhangsan
sge=18
Hobby="paly pingpong、badminton"
home_address="xi`an"

3.变量的分类和引用

(1)自定义变量:

定义:

变量名=变量值

引用:

Shell 编程基础_bash{变量名}

查看环境变量:

set

取消变量:

unset 变量名

unset -v 取消变量

unset -f 取消函数

注:unset–默认取消变量,当参数不是变量时,才取消函数;

且不能取消只读变量

user_name=wan           //定义变量
$user_name //引用变量
$user_name //引用变量
set //查看变量
set | grep ^user_name //查看变量
unset user_name //取消变量

注:只读变量仅在当前shell生效,子shell不生效

(2)只读变量:

特点:变量值不能被修改,且不能取消

定义:

readonly 变量名=变量值

eclare -r 变量名=变量值

查看:

readonly

[root@wan ~]# readonly my_name=zhangshuaige
[root@wan ~]# declare -r my_age=18
[root@wan ~]# readonly

注:用户自定义的只读变量,在系统重启后自动取消

(3)环境变量:

定义环境变量

[root@wan ~]# dev_backup=/dev/sda1
[root@wan ~]# export dev_backup //方法一
[root@wan ~]# export back_httpd=/etc/http/ //方法二

查看环境变量:

[root@wan ~]# env | grep dev_backup    
[root@wan ~]# env | grep back_httpd
[root@wan ~]# printenv | grep back_httpd
[root@wan ~]# printenv | grep dev_backup

注:这种定义方法(命令行定义)进在当前shell和当前shell的子shell中有效;

让环境变量的修改在退出shell再次登录时仍有效,需要在相关配置文件中修改;

Bash的初始化文件有:/etc/profile、/.bash_profile、/.bash_login、/.profile、/.bashrc、/etc/bashrc

Shell 编程基础_bash_02

区别: bash_profile只在会话开始的时候读取一次,而bashrc则每次打开终端时都会读取

1)配置文件的执行顺序
/etc/profile-->/etc/profile.d/*.sh-->~/.bash_profile-->/etc/bashrc-->~./.bashrc
2)登录式shell的配置文件执行顺序
(清除所有变量,通过文件重新读入)
a.直接通过终端输入账号密码登录
b.使用“su -UserName”切换的用户
执行顺序:(影响该shell的配置文件)
/etc/profile-->/etc/profile.d/*.sh-->~/.bash_profile-->~./.bashrc-->/etc/bashrc
3)非登录式shell配置文件执行顺序
(会继承上一个shell的全部变量):
a.su UserName
b.图形界面下打开终端
c.执行脚本(进入子shell)
d.任何其他的bash实例
执行顺序:(影响该shell的配置文件)
~./.bashrc-->/etc/bashrc-->/etc/profile.d/*.sh

注:让环境变量的修改在退出shell再次登录时仍有效,需要在相关配置文件中修改

/etc/profile /etc/profile.d

(4)位置变量:
[root@wan day2]# vim ex1.sh
echo "姓名:$1"
echo "年龄:$2"
echo "性别:$3"
[root@wan day2]# chmod +x ex1.sh
[root@wan day2]# ./ex1.sh
姓名:
年龄:
性别:
E-mail:
[root@wan day2]# ./ex1.sh 张帅哥 18 男 [email protected]
姓名:张帅哥
年龄:18
性别:男
E-mail:[email protected]
(5)预定义变量:
$0 脚本名
$* 所有的参数
$@ 所有的参数
$# 参数的个数
$$ 当前进程的PID
$! 上一个后台进程的PID
$? 上一个命令的返回值 0表示成功

示例:

[root@wan day2]# vim ex1.sh
echo "姓名:$1"
echo "年龄:$2"
echo "性别:$3"
echo "E-mail:$4"
echo "------------------------------->"
echo "脚本名:$0"
echo "脚本个数:$#"
echo "脚本参数:$*"
echo "脚本参数:$@"
echo "上一个命令执行成功与否:$?"

[root@wan day2]# ./ex1.sh {2..10}
姓名:2
年龄:3
性别:4
E-mail:5
------------------------------->
脚本名:./ex1.sh
脚本个数:9
脚本参数:2 3 4 5 6 7 8 9 10
脚本参数:2 3 4 5 6 7 8 9 10
上一个命令执行成功与否:0

区分点:$* 、 $@ 的区别:

# set -- "I am" test command
[root@localhost Scripts]# for i in "$*";do echo $i;done
I am test command
[root@localhost Scripts]# for i in "$@";do echo $i;done
I am
test
command
[root@localhost Scripts]# for i;do echo $i;done
I am
test
command

注:$@ 和默认不写 执行效果一样

Tip:

常见命令错误码:

1>命令没发现 127

2>没有文件或目录 2

3>变量定义错误 127

4>语法错误 2

4.变量的赋值

(1)直接赋值(显式赋值)

变量名=变量值

user_name="zhang san"
(2)使用 read 从键盘读入
[root@wan day2]# read num
10
[root@wan day2]# echo $num
10
[root@wan day2]# read
20
[root@wan day2]# echo $REPLY
20
[root@wan day2]# vim +  ex2.sh
echo -n "请输入管理员用户名:"
read admin_user
echo "---------------->"
read -p "请输入普通用户的用户名:" user_name
echo $admin_user
echo $user_name

[root@wan day2]# chmod +x ex2.sh
[root@wan day2]# ./ex2.sh
请输入管理员用户名:root
---------------->
请输入普通用户的用户名:wan
root
wan
(3)使用read命令:
[root@wan day2]# read -p "请输入该用户的密码:"  passwd
请输入该用户的密码:123
[root@wan day2]# echo $passwd
123
(4)使用位置变量或者环境变量:
[root@wan day2]# vim ex3.sh  +
name=$1
user_name=$USER
echo $name
echo $user_name
[root@wan day2]# chmod +x ./ex3.sh
[root@wan day2]# ./ex3.sh wan
wan
root
(5)使用命令的输出
[root@wan day2]# fun=`ls /root/`
[root@wan day2]# echo $fun
[root@wan day2]# fun=$(ls /root/)
[root@wan day2]# echo $fun
(5)从文件读取
[root@system1 day2]# cut -d: -f1 /etc/passwd > user.lst
# for循环
for user in `cat user.lst`
do
echo $user
done

# 或使用while循环
while read user
do
echo $user
done < user.lst

5.引号的使用

“” ‘’ ``

单引号(' ')单引号括起来的字符都作为普通字符出现
双引号(" ")双引号括起来的字符,除“$”、“\”、“'”和“"”这几个字符仍是特殊字符并保留其特殊功能
外,其余字符仍作为普通字符对待,
反引号(``)。反引号括起来的字串被Shell解释为命令,在执行时,Shell首先执行该命令,并以它的
标准输出结果取代整个反引号(包括两个反引号)部分
[root@wan day2]# echo "系统登录用户:$USER"
系统登录用户:root
[root@wan day2]# echo '系统登录用户:$USER'
系统登录用户:$USER
[root@wan day2]# echo `ls -lh /etc/httpd/conf.d/`
total 16K -rw-r--r--. 1 root root 2.9K Apr 2 21:13 autoindex.conf -rw-r--r--. 1 root root 366 Apr 2 21:14 README -rw-r--r--. 1 root root 1.3K Nov 27 2019 userdir.conf -rw-r--r--. 1 root root 824 Nov 27 2019 welcome.conf

注:引号的嵌套使用,必须单双引号错开使用

6.变量的作用域

(1)全局变量:

​ 全局变量可以在脚本中定义,也可以在某个函数中定义。在脚本中定义的变量都是全局变量,其作
​ 用域为从被定义的地方开始,一直到Shell脚本结束或者被显式地删除

函数体外定义全局变量

#!/bin/bash
#定义函数
func()
{
#输出变量x的值
echo "$v1"
#修改变量x的值
v1=200
} #
在脚本中定义变量x
v1=100
#调用函数
func
#输出变量x的值
echo "$v1"

函数体内定义全局变量

#!/bin/bash
#定义函数
func()
{
#使用local关键字定义局部变量
local v2=200
} #
调用函数
func
#输出变量的值
echo "$v2"
(2)局部变量:

与全局变量相比,局部变量的使用范围较小,通常仅限于某个程序段访问,例如函数内部 ;

在Shell语言中,可以在函数内部通过local关键字定义局部变量 ;

函数的参数也是局部变量

#!/bin/bash
#定义函数
func()
{
#输出全局变量v1的值
echo "global variable v1 is $v1"
#定义局部变量v1
local v1=2
#输出局部变量v1的值
echo "local variable v1 is $v1"
} #
定义全局变量v1
v1=1
#调用函数
func
#输出全局变量v1的值
echo "global variable v1 is $v1"

6.变量的运算:

[root@wan day2]# echo $((3+8*99/9))
91
[root@wan day2]# echo $[3+8*99/9]
91
[root@wan day2]# let num=3+8*99/9
[root@wan day2]# echo $num
91
[root@wan day2]# echo 3+8*99/9 | bc
91
[root@wan day2]# expr 3 + 5 / 4 //运算符前后必须有空格
4
[root@wan day2]# declare -i num=2+5
[root@wan day2]# echo $num
7
[root@wan day2]# awk ' BEGIN {print 3+4*5/6}'
6.33333

6.字符串的处理:

[root@localhost ~]# str1="hello world"
[root@localhost ~]# echo ${#str1}
11
变量截取
指定起始位置,一直到结束
[root@localhost ~]# echo ${str1:1}
ello world
指定长度,不指定起始位置默认从开头开始
[root@localhost ~]# echo ${str1::3}
hel
指定起始位置和长度
[root@localhost ~]# echo ${str1:1:3}
ell
从右边第几个字符开始,及字符的个数
[root@localhost ~]# echo ${str1:0-1:1}
d 输
出右边的几个字符
[root@localhost ~]# echo ${str1:0-5}
world
[root@localhost ~]# echo ${str1: -5}
world
注意:下面写法会输出全部,以${parameter:-default}方式,默认是提取完整地字符串
[root@localhost ~]# echo ${str1:-5}
hello world
删除字符串:
// 获取后缀名tar.gz
[root@localhost ~]# filename=testfile.tar.gz
[root@localhost ~]# file=${filename#*.}
[root@localhost ~]# echo $file
tar.gz
// 获取后缀名gz
[root@localhost ~]# filename=testfile.tar.gz
[root@localhost ~]# file=${filename##*.}
[root@localhost ~]# echo $file
gz
//截取testfile.tar
[root@localhost ~]# filename=testfile.tar.gz
[root@localhost ~]# file=${filename%.*}
[root@localhost ~]# echo $file
testfile.tar
//截取testfile
[root@localhost ~]# filename=testfile.tar.gz
[root@localhost ~]# file=${filename%%.*}
[root@localhost ~]# echo $file
testfile
[root@wan day2]# dirname /usr/local/bin/            //取出文件所在目录
/usr/local
[root@wan day2]# basename /usr/local/bin/ //取出该路径下的文件
bin
[root@wan day2]#

字符串变量的替换:

[root@wan day2]# words="this is a boy"
[root@wan day2]# echo $words
this is a boy
[root@wan day2]# echo ${words/boy/girl}
this is a girl
[root@wan day2]# echo ${words//is/IS}
thIS IS a boy

7.shell 变量扩展配置

示例:

-示例:用法1,如果parameter变量值为空或未赋值,则返回word字符串代替变量的值
//变量未赋值,输出为空。
[root@localhost ~]# echo $var1
[root@localhost ~]# var2=${var1:-hello}
[root@localhost ~]# echo $var2
hello
-示例:用法2,如果parameter变量值有值,则变量返回parameter变量的值
[root@localhost ~]# var1="hello"
[root@localhost ~]# echo $var1
hello
[root@localhost ~]# var2=${var1:-world}
[root@localhost ~]# echo $var2
hello
=示例:用法1,如果parameter变量值为空或未赋值,则返回word字符串代替变量的值
注意和-,不同点在于var1没有赋值,将word赋值刚给var1
[root@localhost ~]# unset var1 var2
[root@localhost ~]# var2=${var1:=world}
[root@localhost ~]# echo $var2
world
[root@localhost ~]# echo $var1
world
=示例:用法2,如果parameter变量值有值,则返回parameter变量的值
[root@localhost ~]# unset var1 var2
[root@localhost ~]# var1=hello
[root@localhost ~]# var2=${var1:=world}
[root@localhost ~]# echo $var2
hello
[root@localhost ~]# echo $var1
hello
?示例:
{parameter:?word}的作用是: 如果 parameter 变量值为空或未赋值, 那么 word 字符
串将被作为标准错误输出, 否则输出变量的值。
[root@localhost ~]# unset var1 var2
[root@localhost ~]# var2=${var1:?world}
-bash: var1: world
[root@localhost ~]# unset var1 var2
[root@localhost ~]# var1=hello
[root@localhost ~]# var2=${var1:?world}
[root@localhost ~]# echo $var2
hello
[root@localhost ~]# echo $var1
hello
+示例:
${parameter:+word}的作用是: 如果 parameter 变量值为空或未赋值, 则什么都不
做, 否则 word 字符串将替代变量的值
[root@localhost ~]# unset var1 var2
[root@localhost ~]# var2=${var1:+world}
[root@localhost ~]# echo $var2
[root@localhost ~]# unset var1 var2
[root@localhost ~]# var1=hello
[root@localhost ~]# var2=${var1:+world}
[root@localhost ~]# echo $var2
world
[root@localhost ~]# echo $var1
hello

三、Shell 条件测试

1.条件测试基本语法

在Shell程序中,用户可以使用测试语句来测试指定的条件表达式的条件的真或者假。当指定的条件

为真时,整个条件测试的返回值为0;反之,如果指定的条件为假,则条件测试语句的返回值为非0值

格式1: test 条件表达式

格式2: [ 条件表达式 ]

格式3: [[ 条件表达式 ]]

2.文件测试

Shell 编程基础_bash_03

//普通文件测试
[root@localhost ~]# touch file1.txt
[root@localhost ~]# [ -f file1.txt ] && echo yes || echo no
yes
//目录测试
[root@localhost ~]# [ -d /tmp ] && echo yes || echo no
yes
//测试文件属性
[root@localhost ~]# ll file1.txt
-rw-r--r-- 1 root root 0 8月 28 12:30 file1.txt
[root@localhost ~]# [ -r file1.txt ] && echo yes || echo no
yes
[root@localhost ~]# [ -x file1.txt ] && echo yes || echo no
no
//测试文件时间新旧
[root@wan ~]# mkdir ex1.sh
[root@wan ~]# mkdir ex2.sh
[root@wan ~]# [ ex1.sh -nt ex2.sh ]
[root@wan ~]# echo $?
1
[root@wan ~]# [ ex1.sh -ot ex2.sh ]
[root@wan ~]# echo $?
0

3.字符串测试

Shell 编程基础_bash_04

//-n如果字符串长度不为零输出yes,否则输出no
[root@localhost ~]# [ -n "hello" ] && echo yes || echo no
yes
[root@localhost ~]# [ -n "" ] && echo yes || echo no
no
//-z如果字符串长度为零输出yes,否则输出no
[root@localhost ~]# [ -z "hello" ] && echo yes || echo no
no
[root@localhost ~]# [ -z "" ] && echo yes || echo n
yes
// 字符串相等比较
注意:=的左右有空格,没有空格将会导致逻辑错误。
[root@localhost ~]# [ "HELO" = "hello" ] && echo yes || echo no
no
[root@localhost ~]# [ "HELO" != "hello" ] && echo yes || echo no
yes

4.整数测试

Shell 编程基础_shell_05

示例:

[root@localhost ~]# [ 5 -gt 3 ] && echo yes || echo no
yes
[root@localhost ~]# [ `id -u` -eq 0 ] && echo admin || echo other
admin
[root@localhost ~]# su - student
[student@localhost ~]$ [ `id -u` -eq 0 ] && echo admin || echo other
other

5.逻辑运算符操作

Shell 编程基础_变量名_06

[root@localhost ~]# [ -f /etc/hosts -a -f /etc/services ] && echo yes || echo no
yes
[root@localhost ~]# [[ -f /etc/hosts && -f /etc/services ]] && echo yes || echo
no
yes

6.命令执行顺序

; --命令的顺序执行# date ; ls -l /etc/passwd
&& --前面命令执行不成功,后面的命令不执行# mkdir /mnt/iso && mount /dev/sr0 /mnt/iso
|| --如果前面命令成功,后面就不执行,如果前面不成功后面就执行

ocalhost ~]# [ “HELO” != “hello” ] && echo yes || echo no
yes

#### 4.整数测试

[外链图片转存中...(img-mwj38RkR-1599835049075)]

示例:

```shell
[root@localhost ~]# [ 5 -gt 3 ] && echo yes || echo no
yes
[root@localhost ~]# [ `id -u` -eq 0 ] && echo admin || echo other
admin
[root@localhost ~]# su - student
[student@localhost ~]$ [ `id -u` -eq 0 ] && echo admin || echo other
other

5.逻辑运算符操作

[外链图片转存中…(img-qHXA8yXi-1599835049076)]

[root@localhost ~]# [ -f /etc/hosts -a -f /etc/services ] && echo yes || echo no
yes
[root@localhost ~]# [[ -f /etc/hosts && -f /etc/services ]] && echo yes || echo
no
yes

6.命令执行顺序

; --命令的顺序执行# date ; ls -l /etc/passwd
&& --前面命令执行不成功,后面的命令不执行# mkdir /mnt/iso && mount /dev/sr0 /mnt/iso
|| --如果前面命令成功,后面就不执行,如果前面不成功后面就执行


标签:wan,Shell,day2,编程,基础,echo,sh,root,localhost
From: https://blog.51cto.com/u_14904176/5971319

相关文章

  • 1、shell简介
    shell简介shell快捷键筛选信息快捷键符号命令执行:!! 执行上一条命令!【num】 执行历史命令中的第num行命令Ctrl【关键字】 执行内容匹配的......
  • 两个系统介绍shell脚本的网站,啥都有
    Shellifelse语句(详解版)(biancheng.net)Shell判断是否为目录-Shell判断文件是否是目录-嗨客网(haicoder.net)......
  • 比较系统介绍shell脚本的一系列文章
     点进这个博主的标签分类,可以看到一系列文章(4条消息)Shell脚本入门01:格式与基础使用_NaisuXu的博客-CSDN博客_shell脚本格式(4条消息)Linux相关_NaisuXu的博客-C......
  • C++基础
    输出语句#include<iostream>intmain(){std::cout<<"HelloWorld!\n";//输出HelloWorldstd::cout<<std::endl;//输出换行}如果要使用cout输出变量......
  • Shell笔记:编写脚本常用语法
    本文记录的是工作中编写脚本的常用语法整理,比较零散,有错欢迎指正。一、文件第一行文件的第一行通常为#!/bin/bash或#!/bin/sh,#!用于指定这个脚本文件使用什么解释......
  • Java基础类String学习分析
    目录1String不可变性2不可变的好处3String+和StringBuilder效率差异4String,StringBufferandStringBuilder5String与JVM内存管理6Stringapi方法1String不可变......
  • 基础_cifar10_model
    今天进一步在cifar10数据集上解决几个问题:1、比较一下序贯和model,为什么要分成两块;2、同样的条件下,我去比较一下序贯和model。这个例子作为今天的晚间运行。1、比较一......
  • 电脑面试两道问题(python+shell)
    最近面试电脑代码面试遇到两个问题,供大家参考一下一、python脚本:手写一个函数,实现两个数相加,并使用unittest与pytest工具测试函数正确性。1.unnitest进行测试:importun......
  • Java编程思想22
    3.关于volatile  volatile关键字确保了应用中的可视性。如果你将一个域声明为volatile的,那么只要对这个域产生了写操作,那么所有的读操作就都可以看到这个修改。即便使用......
  • 套接字编程
                           ......