1、请描述网桥、集线器、二层交换机、三层交换机、路由器的功能、使用场景与区别。
网桥也叫桥接器,是连接两个局域网的一种存储/转发设备,用来连接不同网段。 集线器称为“Hub”,主要功能是对接收到的信号进行再生整形放大,以扩大网络的传输距离,同时把所有节点集中在以它为中心的节点上。 二层交换机工作于OSI模型的第2层(数据链路层),可识别数据包中的MAC地址信息,根据MAC地址进行转发,并将这些MAC地址与对应的端口记录在自己内部的一个地址表中。 三层交换机就是具有部分路由器功能的交换机,三层交换机的最重要目的是加快大型局域网内部的数据交换,所具有的路由功能也是为这目的服务的,能够做到一次路由,多次转发。对于数据包转发等规律性的过程由硬件高速实现,而像路由信息更新、路由表维护、路由计算、路由确定等功能,由软件实现。 路由器(Router),是连接因特网中各局域网、广域网的设备,它会根据信道的情况自动选择和设定路由,以最佳路径,按前后顺序发送信号。
2、IP地址的分类有哪些?子网掩码的表示形式及其作用
IPv4 地址分类: 点分十进制:0-255 0000 0000 - 1111 1111 0.0.0.0-255.255.255.255 A类: 0 000 0000 - 0 111 1111: 1-127 网络数:126, 127 每个网络中的主机数:2^24-2 默认子网掩码:255.0.0.0 私网地址:10.0.0.0/8 B类: 10 00 0000 - 10 11 1111:128-191 网络数:2^14 每个网络中的主机数:2^16-2 默认子网掩码:255.255.0.0 私网地址:172.16.0.0/16-172.31.0.0/16 C类: 110 0 0000 - 110 1 1111: 192-223 网络数:2^21 每个网络中的主机数:2^8-2 默认子网掩码:255.255.255.0 私网地址:192.168.0.0/24-192.168.255.0/24 D类:组播 1110 0000 - 1110 1111: 224-239 E类: 240-255 子网掩码的设定必须遵循一定的规则。与二进制IP地址相同,子网掩码由1和0组成,且1和0分别连续。子网掩码的长度也是32位,左边是网络位,用二进制数字“1”表示,1的数目等于网络位的长度;右边是主机位,用二进制数字“0”表示,0的数目等于主机位的长度。这样做的目的是为了让掩码与ip地址做按位与运算时用0遮住原主机数,而不改变原网络段数字,而且很容易通过0的位数确定子网的主机数(2的主机位数次方-2,因为主机号全为1时表示该网络广播地址,全为0时表示该网络的网络号,这是两个特殊地址)。对于A类地址来说,默认的子网掩码是255.0.0.0;对于B类地址来说默认的子网掩码是255.255.0.0;对于C类地址来说默认的子网掩码是255.255.255.0。 只有通过子网掩码,才能表明一台主机所在的子网与其他子网的关系,使网络正常工作。利用子网掩码可以把大的网络划分成子网,即VLSM(可变长子网掩码),也可以把小的网络归并成大的网络即超网。
3、计算机网络的分成模型有哪些(OSI模型和TCP/IP模型),每一层的功能及涉及到的物理设备有哪些。
(1)OSI模型:物理层、数据链路层、网络层、传输层、会话层、表示层和应用层 ①物理层(Physical layer):利用物理传输介质为数据链路层提供物理连接, 如:集线器、网线、光纤、同轴电缆等; 在这一层,数据的单位称为比特(bit)。 物理层定义的典型规范代表包括:EIA/TIA RS-232、EIA/TIA RS-449、V.35、RJ-45等 ②数据链路层(Data link layer):将数据分帧,并处理流控制,屏蔽物理层, 为网络层提供一个数据链路的连接,进行几乎无差错的数据传输,如:网卡、网桥、二层交换机; 该层的作用包括:物理地址寻址、数据的成帧、流量控制、数据的检错、重发等。 在这一层,数据的单位称为帧(frame)。数据链路层协议的代表包括:SDLC、HDLC、PPP、STP、 帧中继等。 ③网络层(Network layer):负责路由转发和控制网络拥塞,如:路由器、三层交换机等; 在这一层,数据的单位称为数据包(packet)。网络层协议的代表包括:IP、IPX、RIP、OSPF等。 ④传输层(Transport layer):负责将上层数据分段并提供端到端的、可靠(TCP) 或不可靠(UDP)的数据传输;在这一层,数据的单位称为数据段(segment)。 传输层协议的代表包括:TCP、UDP、SPX等。 ⑤会话层(Session layer):负责两个节点之间的连接和断开;管理主机之间的会话进程, 即负责建立、管理、终止进程之间的会话。会话层还利用在数据中插入校验点来实现数据的同步。 ⑥表示层(Presentation layer):负责加密和解密;表示层的数据转换包括数据的加密、 压缩、格式转换等。 ⑦应用层(Application layer):用于进程间通信,常用的协议有HTTP、FTP、SMTP、TELNET等 (2)TCP/IP模型:网络接入层 、网际互联层、传输层、应用层 ① 网络接入层:与OSI参考模型中的物理层和数据链路层相对应,负责监视数据在主机和网络之 间的交换; ②网际互连层:相当于OSI的网络层,主要处理主机到主机间的通信;该层定义了分组格式和协议, 即IP协议(Internet Protocol)。除了需要完成路由的功能外,也可以完成将不同类型的网络 (异构网)互连的任务,也需要完成拥塞控制的功能。 ③传输层:对应于OSI参考模型的传输层,为应用层实体提供端到端的通信功能,保证了数据包的 顺序传送及数据的完整性,该层定义了两种服务质量不同的协议:传输控制协议TCP(transmission control protocol)和用户数据报协议UDP(user datagram protocol)。 ④应用层:对应于OSI参考模型的会话层、表示层和应用层,面向不同的网络应用引入了不同的 应用层协议,如:文件传输协议(File Transfer Protocol,FTP)、虚拟终端协议(TELNET)、 超文本链接协议(Hyper Text Transfer Protocol,HTTP)等。
4、如何将Linux主机接入到TCP/IP网络,请描述详细的步骤。(手动指定的方式)
(1)vim /etc/sysconfig/network 添加hostname (2)vim /etc/sysconfig/network-script/ifcfg-eth0 指定IPADDR,GETWAY,NATMARSK,DNS,BOOTPROTO=static,ONBOOT=yes (3)service network restart
5、为Linux主机配置网络信息的方式有哪些,请描述各个过程。
DHCP vim /etc/sysconfig/network-script/ifcfg-eth0 ifconfig INTERFACE IP netmask MASK ip addr { add | del } IFADDR dev STRING
6、写一个脚本,使用ping命令探测172.16.250.1-172.16.250.254之间的所有主机的在线状态;
在线的主机使用绿色显示;
不在线的主使用红色显示;
#!/bin/bash # for i in { 1 254 };do ping -c 1 -w 1 172.16.250.$i &> /dev/null if [ $? -eq 0 ] ; then echo -e " \033[;32m 172.16.250.$i \033[0m" else echo -e " \033[;31m 172.16.250.$i \033[0m" fi done
7、详细描述每个网络接口的配置文件中各个参数的含义和其所对应的值;
DEVICE #网卡名 BOOTPROTO #ip地址分配方式, dhcp、static HWADDR #MAC地址 NM_CONTROLLED="yes" #network mamager参数, ONBOOT #网卡是否开机激活 TYPE #网络类型 IPV6INIT=no #禁止IPV6 USERCTL=no #是否允许非root用户控制该设备,为no,只能root用户更改 IPADDR= #IP ADDR GATEWAY #gatway地址 NETMASK #掩码 DNS1 #dns1地址 DNS2 #dns2地址
8、如何给网络接口配置多个地址,有哪些方式?
ifconfig eth0:0 192.168.0.22/24 up ip addr add 192.168.100.124/24 dev eth0:0 复制为/etc/sysconfig/network-scripts/ifcfg-eth0:0, 然后更改配置文件内的网卡名为eth0:0,然后更换新的IP地址,重启动网卡
9、常用的网络管理类工具有哪些,并用示例形式描述他们的使用方法。
ifconfig命令 ifconfig [interface] # ifconfig -a # ifconfig INTERFACE [up|down] ifconfig interface [aftype] options | address ... # ifconfig INTERFACE IP/mask [up] # ifconfig INTERFACE IP netmask MASK route命令 路由管理命令 查看:route -n 添加:route add route add [-net|-host] target [netmask Nm] [gw Gw] [[dev] If] 目标:192.168.1.3 网关:172.16.0.1 ~]# route add -host 192.168.1.3 gw 172.16.0.1 dev eth0 目标:192.168.0.0 网关:172.16.0.1 ~]# route add -net 192.168.0.0 netmask 255.255.255.0 gw 172.16.0.1 dev eth0 ~]# route add -net 192.168.0.0/24 gw 172.16.0.1 dev eth0 默认路由,网关:172.16.0.1 ~]# route add -net 0.0.0.0 netmask 0.0.0.0 gw 172.16.0.1 ~]# route add default gw 172.16.0.1 删除:route del route del [-net|-host] target [gw Gw] [netmask Nm] [[dev] If] 目标:192.168.1.3 网关:172.16.0.1 ~]# route del -host 192.168.1.3 目标:192.168.0.0 网关:172.16.0.1 ~]# route del -net 192.168.0.0 netmask 255.255.255.0 netstat命令: netstat - Print network connections, routing tables, interface statistics, masquerade connections, and multicast memberships 显示网络连接: netstat [--tcp|-t] [--udp|-u] [--raw|-w] [--listening|-l] [--all|-a] [--numeric|-n] [--extend|-e[--extend|-e]] [--program|-p] -t: tcp协议相关 -u: udp协议相关 -w: raw socket相关 -l: 处于监听状态 -a: 所有状态 -n: 以数字显示IP和端口; -e:扩展格式 -p: 显示相关进程及PID 常用组合: -tan, -uan, -tnl, -unl 显示路由表: netstat {--route|-r} [--numeric|-n] -r: 显示内核路由表 -n: 数字格式 显示接口统计数据: netstat {--interfaces|-I|-i} [iface] [--all|-a] [--extend|-e] [--program|-p] [--numeric|-n] # netstat -i # netstat -I IFACE ip命令: ip - show / manipulate routing, devices, policy routing and tunnels ip [ OPTIONS ] OBJECT { COMMAND | help } OBJECT := { link | addr | route } link OBJECT: ip link - network device configuration set dev IFACE 可设置属性: up and down:激活或禁用指定接口; show [dev IFACE]:指定接口 [up]:仅显示处于激活状态的接口 ip address - protocol address management ip addr { add | del } IFADDR dev STRING [label LABEL]:添加地址时指明网卡别名 [scope {global|link|host}]:指明作用域 global: 全局可用; link: 仅链接可用; host: 本机可用; [broadcast ADDRESS]:指明广播地址 例如: ip addr add 192.168.1.111/24 dev eth0 label eth0:0 ip address show - look at protocol addresses [dev DEVICE] [label PATTERN] [primary and secondary] ip address flush - flush protocol addresses 使用格式同show ip route - routing table management ip route add 添加路由:ip route add TARGET via GW dev IFACE src SOURCE_IP TARGET: 主机路由:IP 网络路由:NETWORK/MASK 添加网关:ip route add defalt via GW dev IFACE ip route delete 删除路由:ip route del TARGET ip route show ip route flush [dev IFACE] [via PREFIX] ss命令: 格式:ss [OPTION]... [FILTER] 选项: -t: tcp协议相关 -u: udp协议相关 -w: 裸套接字相关 -x:unix sock相关 -l: listen状态的连接 -a: 所有 -n: 数字格式 -p: 相关的程序及PID -e: 扩展的信息 -m:内存用量 -o:计时器信息 FILTER := [ state TCP-STATE ] [ EXPRESSION ]
10、Linux系统软件包管理方法(安装、升级、卸载等操作)有哪些,以及如何管理的。
CentOS系统上rpm命令管理程序包: 安装、卸载、升级、查询、校验、数据库维护 安装: rpm {-i|--install} [install-options] PACKAGE_FILE ... -v: verbose -vv: -h: 以#显示程序包管理执行进度;每个#表示2%的进度 rpm -ivh PACKAGE_FILE ... [install-options] --test: 测试安装,但不真正执行安装过程;dry run模式; --nodeps:忽略依赖关系; --replacepkgs: 重新安装; --nosignature: 不检查来源合法性; --nodigest:不检查包完整性; --noscipts:不执行程序包脚本片断;具体分为以下四类:(可单独选择某类) %pre: 安装前脚本; --nopre %post: 安装后脚本; --nopost %preun: 卸载前脚本; --nopreun %postun: 卸载后脚本; --nopostun 升级: rpm {-U|--upgrade} [install-options] PACKAGE_FILE ... rpm {-F|--freshen} [install-options] PACKAGE_FILE ... upgrage:安装有旧版程序包,则“升级”;如果不存在旧版程序包,则“安装”; freeshen:安装有旧版程序包,则“升级”;如果不存在旧版程序包,则不执行升级操作; rpm -Uvh PACKAGE_FILE ... rpm -Fvh PACKAGE_FILE ... 其他选项与上面安装一样 --oldpackage:降级; --force: 强行升级; 注意: (1)uname -r 不要对内核做升级操作;Linux支持多内核版本并存,因此,对直接安装新版本内核 (2) 如果原程序包的配置文件安装后曾被修改,升级时,新版本的提供的同一个配置文件并不会直接覆盖老版本的配置文件,而把新版本的文件重命名(FILENAME.rpmnew)后保留 查询: rpm {-q|--query} [select-options] [query-options] [select-options] -a: 所有包 -f: 查看指定的文件由哪个程序包安装生成 # rpm -qf /etc/fstab setup-2.5.58-9.el5 -p /PATH/TO/PACKAGE_FILE:针对尚未安装的程序包文件做查询操作; 查询尚未安装的程序包 rpm -qlp /PATH/TO/PACKAGE_FILE --whatprovides CAPABILITY:查询指定的CAPABILITY由哪个包所提供; --whatrequires CAPABILITY:查询指定的CAPABILITY被哪个包所依赖; [query-options] --changelog:查询rpm包的changlog (制作的,非作者发布的) -c: 查询程序的配置文件 -d: 查询程序的生成文档 -i: information -l: 查看指定的程序包安装后生成的所有文件; --scripts:程序包自带的脚本片断 -R: 查询指定的程序包所依赖的CAPABILITY; --provides: 列出指定程序包所提供的CAPABILITY; --conflicts:列出创建包与哪些包可能冲突 用法: -qi PACKAGE, -qf FILE, -qc PACKAGE, -ql PACKAGE, -qd PACKAGE -qpi PACKAGE_FILE, -qpl PACKAGE_FILE, ... -qa 卸载: rpm {-e|--erase} [--allmatches] [--nodeps] [--noscripts] [--notriggers] [--test] PACKAGE_NAME ... 校验: rpm {-V|--verify} [select-options] [verify-options] S file Size differs M Mode differs (includes permissions and file type) 5 digest (formerly MD5 sum) differs D Device major/minor number mismatch L readLink(2) path mismatch U User ownership differs G Group ownership differs T mTime differs P caPabilities differ 包来源合法性验正及完整性验正: 完整性验正:SHA256 来源合法性验正:RSA 公钥加密: 对称加密:加密、解密使用同一密钥; 非对称加密:密钥是成对儿的, public key: 公钥,公开所有人 secret key: 私钥, 不能公开 导入所需要公钥: rpm --import /PATH/FROM/GPG-PUBKEY-FILE CentOS 7发行版光盘提供的密钥文件:RPM-GPG-KEY-CentOS-7 数据库重建: rpm {--initdb|--rebuilddb} initdb: 初始化 如果事先不存在数据库,则新建之;否则,不执行任何操作; rebuilddb:重建 无论当前存在与否,直接重新创建数据库; 回顾:Linux程序包管理的实现、rpm包管理器 rpm命令实现程序管理: 安装:-ivh, --nodeps, --replacepkgs 卸载:-e, --nodeps 升级:-Uvh, -Fvh, --nodeps, --oldpackage 查询:-q, -qa, -qf, -qi, -qd, -qc, -q --scripts, -q --changlog, -q --provides, -q --requires 校验:-V 导入GPG密钥:--import, -K, --nodigest, --nosignature 数据库重建:--initdb, --rebuilddb Linux程序包管理(2) CentOS: yum, dnf URL: ftp://172.16.0.1/pub/ YUM: yellow dog, Yellowdog Update Modifier yum repository: yum repo 存储了众多rpm包,以及包的相关的元数据文件(放置于特定目录下:repodata); 文件服务器: ftp:// http:// nfs:// file:/// yum客户端: 配置文件: /etc/yum.conf:为所有仓库提供公共配置 /etc/yum.repos.d/*.repo:为仓库的指向提供配置 仓库指向的定义: man yum.conf [repositoryID] name=Some name for this repository baseurl=url://path/to/repository/ enabled={1|0} 是否启用 gpgcheck={1|0} 是否检查源文件合法性和完整性 gpgkey=URL enablegroups={1|0} failovermethod={roundrobin|priority} 默认为:roundrobin,意为随机挑选; cost= 默认为1000 教室里的yum源:http://172.16.0.1/cobbler/ks_mirror/CentOS-6.6-x86_64/ CentOS 6.6 X84_64 epel: http://172.16.0.1/fedora-epel/6/x86_64/ yum命令的用法: yum [options] [command] [package ...] command is one of: * install package1 [package2] [...] * update [package1] [package2] [...] * update-to [package1] [package2] [...] * check-update * upgrade [package1] [package2] [...] * upgrade-to [package1] [package2] [...] * distribution-synchronization [package1] [package2] [...] * remove | erase package1 [package2] [...] * list [...] * info [...] * provides | whatprovides feature1 [feature2] [...] * clean [ packages | metadata | expire-cache | rpmdb | plugins | all ] * makecache * groupinstall group1 [group2] [...] * groupupdate group1 [group2] [...] * grouplist [hidden] [groupwildcard] [...] * groupremove group1 [group2] [...] * groupinfo group1 [...] * search string1 [string2] [...] * shell [filename] * resolvedep dep1 [dep2] [...] * localinstall rpmfile1 [rpmfile2] [...] (maintained for legacy reasons only - use install) * localupdate rpmfile1 [rpmfile2] [...] (maintained for legacy reasons only - use update) * reinstall package1 [package2] [...] * downgrade package1 [package2] [...] * deplist package1 [package2] [...] * repolist [all|enabled|disabled] * version [ all | installed | available | group-* | nogroups* | grouplist | groupinfo ] * history [info|list|packages-list|packages-info|summary|addon-info|redo|undo|rollback|new|sync|stats] * check * help [command] 显示仓库列表: repolist [all|enabled|disabled] 显示程序包: list # yum list [all | glob_exp1] [glob_exp2] [...] # yum list {available|installed|updates} [glob_exp1] [...] 安装程序包: install package1 [package2] [...] reinstall package1 [package2] [...] (重新安装) 升级程序包: update [package1] [package2] [...] downgrade package1 [package2] [...] (降级) 检查可用升级: check-update 卸载程序包: remove | erase package1 [package2] [...] 查看程序包information: info [...] 查看指定的特性(可以是某文件)是由哪个程序包所提供: provides | whatprovides feature1 [feature2] [...] 清理本地缓存: clean [ packages | metadata | expire-cache | rpmdb | plugins | all ] 构建缓存: makecache 搜索: search string1 [string2] [...] 以指定的关键字搜索程序包名及summary信息; 查看指定包所依赖的capabilities: deplist package1 [package2] [...] 查看yum事务历史: history [info|list|packages-list|packages-info|summary|addon-info|redo|undo|rollback|new|sync|stats] 安装及升级本地程序包: * localinstall rpmfile1 [rpmfile2] [...] (maintained for legacy reasons only - use install) * localupdate rpmfile1 [rpmfile2] [...] (maintained for legacy reasons only - use update) 包组管理的相关命令: * groupinstall group1 [group2] [...] * groupupdate group1 [group2] [...] * grouplist [hidden] [groupwildcard] [...] * groupremove group1 [group2] [...] * groupinfo group1 [...] yum的命令行选项: --nogpgcheck:禁止进行gpg check; -y: 自动回答为“yes”; -q:静默模式; --disablerepo=repoidglob:临时禁用此处指定的repo; --enablerepo=repoidglob:临时启用此处指定的repo; --noplugins:禁用所有插件; yum的repo配置文件中可用的变量: $releasever: 当前OS的发行版的主版本号; $arch: 平台; $basearch:基础平台; $YUM0-$YUM9 http://mirrors.magedu.com/centos/$releasever/$basearch/os 创建yum仓库: createrepo [options] <directory>
11、如何使用发行版光盘作为yum repository,请描述该过程。
如何使用光盘当作本地yum仓库: (1) 挂载光盘至某目录,例如/media/cdrom # mount -r -t iso9660 /dev/cdrom /media/cdrom (2) 创建配置文件 [CentOS7] name= baseurl=file:/// gpgcheck=0 enabled=
12、写一个脚本,完成以下功能
(1) 假设某目录(/etc/rc.d/rc3.d/)下分别有K开头的文件和S开头的文件若干;
(2) 显示所有以K开头的文件的文件名,并且给其附加一个stop字符串;
(3) 显示所有以S开头的文件的文件名,并且给其附加一个start字符串;
(4) 分别统计S开头和K开头的文件各有多少;
#!/bin/bash # ls /etc/rc.d/rc3.d/K*|awk '{printf "%s Stop \n", $1}'|awk -F'/' '{print $NF}' ls /etc/rc.d/rc3.d/S*|awk '{printf "%s Start \n", $1}'|awk -F'/' '{print $NF}' k_lines=`ls /etc/rc.d/rc3.d/K*|awk '{print NR}'|tail -1` s_lines=`ls /etc/rc.d/rc3.d/S*|awk '{print NR}'|tail -1` echo "k start lines is $k_lines" echo "s start lines is $s_lines"
13、写一个脚本,完成以下功能
(1) 脚本能接受用户名作为参数;
(2) 计算此些用户的ID之和;
[root@www shell]# cat sumuid.sh #!/bin/bash # declare -i sum_uid read -p "Please enter users' name:" u_in for u_test in $u_in;do if id $u_test &> /dev/null;then sum_uid+=`id $u_test | awk '{print $1}' | awk -F'=' '{print $2}' | awk -F'(' '{print $1}'` else echo "$user does not exist! Quit..." exit 1 fi done echo "The uid sum is $sum_uid"
14、写一个脚本
(1) 传递一些目录给此脚本;
(2) 逐个显示每个目录的所有一级文件或子目录的内容类型;
(3) 统计一共有多少个目录;且一共显示了多少个文件的内容类型;
#!/bin/bash # declare -i f_sum=0;b_sum=0;c_sum=0;d_sum=0;l_sum=0;p_sum=0;s_sum=0 for d_in in $*;do if ! [ -d $d_in ];then echo -e "\n$d_in is no such dir" else tree $d_in for f_test in $(ls $d_in);do if [ -L "$d_in/$f_test" ];then let l_sum++ elif [ -b "$d_in/$f_test" ];then let b_sum++ elif [ -c "$d_in/$f_test" ];then let c_sum++ elif [ -d "$d_in/$f_test" ];then let d_sum++ elif [ -f "$d_in/$f_test" ];then let f_sum++ elif [ -p "$d_in/$$f_test" ];then let p_sum++ elif [ -S "$d_in/$f_test" ];then let s_sum++ fi done fi done echo -e "\ndir is $d_sum\nf file is $f_sum\nb file is $b_sum\nc file is $c_sum\nl file is $l_sum\np file is $p_sum\ns file is $s_sum"
15、写一个脚本
通过命令行传递一个参数给脚本,参数为用户名
如果用户的id号大于等于500,则显示此用户为普通用户;
#!/bin/bash # if [ $# -lt 1 ];then echo "At least one username" exit 1 fi if id $1 &> /dev/null;then uid=$(grep "^\<$1\>" /etc/passwd | cut -d: -f3) if [ $uid -ge 500 ];then echo "$1 is regular user" else echo "$1 is system user" fi else echo "$1 is not exists" fi
16、写一个脚本
(1) 添加10用户user1-user10;密码同用户名;
(2) 用户不存在时才添加;存在时则跳过;
(3) 最后显示本次共添加了多少用户;
#!/bin/bash # declare -i num for((i=1;i<11;i++)),do if ! id user$i &> /dev/null;then useradd user$i echo user$i:user$i | chpasswd let num++ fi done echo "Add $num users!"
17、写一脚本,用ping命令测试172.16.250.20-172.16.250.100以内有哪些主机在线,将在线的显示出来;
#!/bin/bash # for i in { 20..100 };do ping -c 1 -w 1 172.16.250.$i &> /dev/null if [ $? -eq 0 ] ; then echo -e " 172.16.250.$i is online!" fi done
18、打印九九乘法表;
#!/bin/bash # for ((i=1;i<=9;i++)){ for((j=1;j<=i;j++));do echo -e -n "$j*$i=$(($i*$j))\t" done echo }
原创文章,作者:N21-孟然,如若转载,请注明出处:http://www.178linux.com/41003
评论列表(1条)
排版不是很好看啊,图如果是自己画的话,那会非常棒