Linux学习笔记
来源:互联网 发布:python 实现tcp连接 编辑:程序博客网 时间:2024/05/16 05:28
目录
- 目录
- 命令行光标快捷键
- Linux通配符
- find命令
- grep命令
- 帮助命令
- 压缩命令
- zip 格式压缩
- gz 格式压缩
- bz2 格式压缩
- 打包命令
- targz 格式压缩
- tarbz2 格式压缩
- 关机重启命令
- shutdown 选项 时间
- 其他关机命令
- 其他重启命令
- 系统运行级别
- 退出登录
- 挂载命令
- 查看登录用户信息
- w命令
- who 命令
- last 查看用户最后一次登录的时间
- wc 命令
- 别名
- 历史命令
- 输出重定向
- 多命令顺序执行
- 管道符
- VIM操作
- 磁盘管理
- df 查看磁盘分区使用状况
- du 统计磁盘上的文件大小
- 分区
- MBR 分区
- GPT分区
- 分区格式化
- swap 分区
- 用户和用户组
- 用户组操作命令
- 用户操作命令
- 其他命令
- Linux软件安装管理
- 源码包
- rpm包安装
- yum源在线安装
- 启动命令
- 关闭SELinux
- Linux权限
- 基本权限的修改
- 修改文件的所有者
- 修改文件的所属组
- 文件的默认权限
- 目录的默认权限
- ACL权限
- sudo权限
- 文件特殊权限
- 不可改变位权限
- Linux日志
- 服务管理
- RPM包默认安装的服务
- 源码包安装的服务
- 进程管理
- 查看进程-ps命令和pstree命令
- 杀死进程
- 修改优先级
- 工作管理
- 工作管理方法
- 后台命令脱离终端
- 查看系统资源
- iptables配置
命令行光标快捷键
- Ctrl+左右键:在单词之间跳转
- Ctrl+a:跳到本行的行首
- Ctrl+e:跳到页尾
- Ctrl+u:删除当前光标前面的文字
- Ctrl+k:删除当前光标后面的文字
- Ctrl+L:进行清屏操作
- Ctrl+y:进行恢复删除做
- Ctrl+w:删除光标前面的单词的字符
Linux通配符
- *:匹配0个或多个任意字符,也就是可以匹配任何字符
- ?:匹配一个任意字符
- []:匹配中括号中任意一个字符
- [-]:匹配中括号中任意一个字符,-代表一个范围
- [^]:逻辑非,表示匹配不是中括号内的一个字符
find命令
- find 路劲 搜索条件 搜索名字
- find /root -name install.log
- find /root -iname install.log
- find /root -user root
- find /root -nouser
- find /root -mtime +10
- find /root -atime -10
- find /root -ctime 10
- find /etc -size +25k
- find /etc -inum 29491202
- find /etc -size +20k -a -size -50k
- find /etc -size +20k -o -size -2k
- find /etc -size +20k -a -size -50k -exec ls -lh {} \;
grep命令
- grep [选项] 字符串 文件名
- grep “size” install.log
- grep -i “size” install.log 忽略大小写
- grep -v “size” install.log 排除字符串
帮助命令
- man 1 ls
- man -f ls / whatis ls / whereis ls
- man -k passwd / apropos passwd
- help 查看shell命令帮助
- info ls 查看超详细的帮助
压缩命令
.zip 格式压缩
- zip 压缩文件名 源文件
- zip -r 压缩文件名 源目录
- unzip 压缩文件名
.gz 格式压缩
- gzip 文件名
- gzip -r 目录名
- gzip -c 文件名 > 压缩文件名
- gzip -d 解压缩
- gunzip 解压缩
.bz2 格式压缩
- bzip2 源文件 不保留源文件
- bzip2 源文件 保留源文件
- 注意:bzip2 不能压缩目录
- bzip2 -d 解压缩
- bunzip2 解压缩
打包命令
- tar -cvf install.tar install 打包
- tar -xvf install.tar 解打包
.tar.gz 格式压缩
- tar -zcvf install.tar.gz install 压缩
- tar -xvcf install.tar.gz 解压缩
- tar -xtvf install.tar.gz 查看压缩包内容
.tar.bz2 格式压缩
- tar -jcvf install.tar.bz2 install 压缩
- tar -jxvf install.tar.bz2 解压缩
关机重启命令
shutdown [选项] 时间
- c 取消上一次的关机命令
- h 关机
- r 重启
- shutdown -h 05:30 & 放入后台执行
其他关机命令
- halt
- poweroff
- init 0
注意:不是很安全,不建议使用
其他重启命令
- reboot
- init 6
系统运行级别
- 0 关机
- 1 单用户
- 2 不完全用户,不包括NFS服务
- 3 完全多用户
- 4 未分配
- 5 图形界面
- 6 重启
- 查看当前系统运行级别:runlevel
退出登录
- logout
挂载命令
- mount 查看系统中已经挂在的设备
- mount -a 按照/etc/fstab挂在文件
- mount [-t 文件系统] [-o 特殊选项] 设备名称 挂载点
- umount 挂载点 卸载命令
- fdisk -l 查看系统硬盘
注意: Linux 默认不支持NTFS系统
#!/bin/bashecho "hello world!"
查看登录用户信息
w命令
命令输出:- USER —登录的用户名
- TTY —登录后系统分配的终端号
- FROM—远程主机名,即从哪儿登录来的
- LOGIN@—何时登录
- IDLE—空闲了多长时间,表示用户闲置的时间。这是一个计时器,一旦用户执行任何操作,该计时器便会被重置
- JCPU—和该终端(tty)连接的所有进程占用的时间,这个时间里并不包括过去的后台作业时间,但却包括当前正在运行的后台作业所占用的时间
- PCPU—指当前进程(即在WHAT项中显示的进程)所占用的时间
- WHAT—当前正在运行进程的命令行
who 命令
last 查看用户最后一次登录的时间
- last 命令默认读取/var/log/lastlog文件内容
- 命令输出: 用户名 登录终端 登录IP 最后一次登录时间
wc 命令
统计文件的字符数,字节数等等信息
- 命令输出:行数 单词数 字节数 文件名
- 选项
–c 统计字节数
– l 统计行数
– m 统计字符数(不能和c一起使用)
– w 统计单词数
– L 打印最长行的长度
– help 显示帮助信息
– version 显示版本信息
别名
- alias ls=ls –color=auto
- 永久有效:~/.bashrc
- 删除别名:unalias 别名
- 删除所有别名:unalias -a
历史命令
history [选项] [历史命令保存文件]
– c:清空历史名利
– w:把缓存中的历史命令保存到历史命令文件中~/.bash_history系统默认保存1000条历史命令,可在/etc/profile里面修改
- 上下箭头调用历史命令
- !n 调用第n条历史命令
- !! 调用上次历史命令
- !字符串 调用字符串开头的历史命令
输出重定向
- 命令 > 文件名 覆盖
- 命令 >> 文件名 追加
- 错误命令 2>文件名
- 错误命令 2>>文件名
- 命令 > 文件名 2>&1
- 命令 >> 文件名 2>&1
- 命令 &> 文件名
- 命令 &>> 文件名
- 命令 > 文件名 2>文件名
- 输入重定向:命令 < 文件名
多命令顺序执行
- 命令1 ; 命令2 多个命令顺序执行,命令之间没有任何逻辑关系
- 命令1 && 命令1 命令1正确执行才执行命令2
- 命令1 || 命令2 命令1不正确执行才执行命令2,命令1正确执行,命令2不执行
- 命令 && echo yes || echo no 判断命令是否正确执行
管道符
- 命令1 | 命令2 命令1正确执行的结果作为命令2的输入
- netstat -an | grep ESTABLISHED | wc -l 查看当前服务器连接数
VIM操作
- Ctrl + f 向上翻页(front)
- Ctrl + b 向下翻页(back)
- Ctrl + d 向下翻半页(down)
- Ctrl + u 向上翻半页(up)
磁盘管理
df 查看磁盘分区使用状况
- l 仅显示本地磁盘
- a 显示所有文件的磁盘使用情况
- h 以1024进制显示磁盘容量
- H 以1000进制显示磁盘容量
- T 显示磁盘分区类型
- t 显示指定类型文件系统的磁盘分区
- x 不显示指定文件系统的磁盘分区
du 统计磁盘上的文件大小
- b 以byte为单位统计文件
- k 以kb为单位统计文件
- m 以MB为单位统计文件
- h 按照1024进制单位统计文件
- H 按照1000进制单位系统计文件
- s 指定统计目标
分区
- 主分区和扩展分区总数不能超过四个
- 扩展分区最多只能有一个
- 扩展分区不能直接存取数据
MBR 分区
- fdisk /dev/sdb
- m 帮助
- n 分区
- p 查看分区
- d 删除分区
- w 写入分区
GPT分区
- parted
- help 查看帮助
- select /dev/sdc
- mklabel gpt 选择分区模式
- print 查看当前分区
- mkpart 创建分区
- mkpart 分区名称 2000 3000
- rm 分区编号 删除分区
- unit GB 指定分区单位
分区格式化
- mkfs.ext3 /dev/sdb3
mkfs -t ext4 /dev/sdb4
swap 分区
- 修改分区编号
- 格式化swap分区 mkswap /dev/sdb6
- 启动swap分区 swapon /dev/sdb6
用户和用户组
- 查看当前系统中用户组信息:cat /etc/group
- 输出格式:组名称:组密码占位符:组编号:组中用户列表
- 查看当前系统中用户组的密码信息:cat /etc/gshadow
- 输出格式:组名称:组密码:组管理者:组中用户列表
- 查看当前系统中用户的信息:cat /etc/passwd
- 输出格式:用户名:密码占位符:用户编号:用户组编号:用户注释信息:用户主目录:shell类型
- 查看当前系统中用户的密码信息:cat /etc/shadow
用户组操作命令
- 增加用户组:groupadd new
- 修改用户组名称:groupmod -n newgroup new
- 修改用户组编号:groupmod -g 668 market
- groupadd -g 888 用户组名称
- 删除用户组:groupdel 用户组名称
- 添加用户:gpasswd -a 用户名 用户组
- 删除用户: gpasswd -d 用户名 用户组
用户操作命令
- 添加用户:useradd -g 用户组 用户名称
- useradd -d /home/xxx 用户名
- 添加备注:usermod -c 备注 备注名称
- 修改用户名:usermod -l 用户名 源用户名
- 修改用户组:usermod -g 用户组 用户名
- 删除用户组:userdel 用户名
- 进制其他用户登录:touch /etc/nologin
其他命令
- 锁定用户命令:passwd -l 用户名
- 解锁用户命令:passwd -u 用户名
- 无密码登录:passwd -b 用户名
- 主要组与附属组
– 添加附属组:gpasswd -a 用户名 附属组
– 切换附属组:newgrp 附属组(用户自己切换)
– 删除附属组:gpasswd -d 用户组 附属组 设置组密码 gpasswd 用户组
id 用户名 显示指定用户信息,包括用户编号、用户名
- groups 用户名 显示用户所在的用户组
- chfn 用户 设置用户资料
- finger 用户 显示用户详细资料
Linux软件安装管理
源码包
- 安装位置: /user/local/软件包/
- 安装准备包:安装gcc
- 源码保存位置:/usr/local/src
- 安装步骤
– 第一步:解压,进入解压缩目录
– 第二步:./configure –prefix=/usr/local/软件名
— 定义需要的功能选项
— 检测系统环境是否符合安装要求
— 把定义好的功能选项和检测系统环境的信息都写入Makerfile文件,用于后续的编辑
– 第二步:make
– 第三步:make install 安装
rpm包安装
- rpm包依赖性
– 树形依赖:a->b->c
– 环形依赖:a->b->c->a
– 模块依赖:www.rpmfind.net - 安装命令:rpm -ivh 包全名
– i (install) 安装
– v (verbose)显示详细信息
– h (hash) 显示进度
– - nodeps 不检查依赖性 - 升级命令:rpm -Uvh 包全名
- 卸载命令:rmp -e 包名
- 查询命令:rmp -q 包名
- rpm -qa 查询系统所有安装的rpm包
- rpm -qi 包名 查询已经rpm包的信息
- rpm -qip 包全名 查询未安装rpm包的信息
- rpm -ql 包名 查询安装位置
- rpm -qlp 包全名 查询未安装包的安装位置
- rpm -qf 系统文件名 查询文件属于哪一个包
- rpm -qR 包名 查询rpm包的依赖信息
- rpm -qRp 包全名 查询未安装rpm包的依赖信息
- rpm -V 包名
- rpm包中文件提取:rpm2cpio 包全名 | cpio -idv .文件绝对路径
yum源在线安装
- yum源位置:/etc/yum.repos.d/CentOS-Base.repos\
- 配置光盘yum源
– 第一步: 挂载光盘 mkdir /mnt/cdrom mount -r iso9660 /dev/sr0 /mnt/cdrom
– 第二步:使网络yum失效 mv CentOS-Base.repos CentOS-Base.repos.bak
– 第三步:使光盘yum生效 将光盘yum源中的baseurl改为光盘的挂载位置 - yum list 查看系统中可以安装的软件包
- yum -y install 包名 安装
- yum -y update 包名 更新
- yum -y remove 包名 卸载
- LANG = en_US 英文 LANG = zh_CN.utf8 中文
- yum grouplist 列出所有可用的软件组列表
- yum groupinstall 软件组名 安装指定软件组,组名可以由grouplist查询出来
- yum groupremove 软件组名 卸载指定软件组
启动命令
- /etc/rc.d/init.d/httpd
- service httpd restart
- 源码包安装:/user/local/apache2/bin/apachectl start
关闭SELinux
- vi /etc/selinux/config
– SELINUX = disabled - 重启
Linux权限
基本权限的修改
- chmod [选项] 模式 文件名
– R 递归 - chmod u+x test
- chmod a=rwx test
- chmod g+w,o+w test
权限对文件的作用
- r:读取文件内容(cat more head tail)
- w:编辑,新增,修改文件内容(vi echo)
– 但不包含删除文件 - x:可执行
权限对目录的作用
- r:可以查询目录下文件名(ls)
- w:具有修改目录结构的权限。如新建文件和目录,删除此目录下文件和目录,重命名此目录下文件和目录,剪切(touch rm mv cp)
- x:可以进入目录(cd)
修改文件的所有者
- chown 用户名 文件或者目录
- chown 用户:用户组 文件或者目录
修改文件的所属组
- chgrp 用户组 文件或者目录
文件的默认权限
- umask 查看默认权限
– 第一位0:文件特殊权限
– 022:文件默认权限 - 文件默认不能建立为执行文件,必须手工赋予执行权限
- 所以文件默认权限最大为666
- 默认权限需要换算成字母再相减
- 建立文件之后的默认权限,为666减去umask值
- 例如:文件默认最大权限666 umask值022
- -rw-rw-rw- 减去 —–w–w- 等于 -rw-r–r–
- 例如:文件默认最大权限666 umask值033
- -rw-rw-rw-减去 —–wx-wx 等于 -rw-r–r–
目录的默认权限
目录默认权限为777
临时修改
– umask 0033- 永久修改
– vi /etc/profile
ACL权限
- dumpe2fs -h /dev/sda5
– #dumpe2fs 命令是查询指定分区详细文件系统信息的命令
– h 仅显示超级快中信息,而不显示磁盘块组的详细信息 - 临时开启ACL权限:mount -o remount,acl /
- 永久开启分区ACL权限:vi /etc/fstab
– UUID=xxxx / ext4 defaults,acl 1 1
– 重新挂载:mount -o remount / - 查看ACL命令:getfacl 文件名
- 设定ACL权限:setfacl 选项 文件名
– m 设定ACL权限
– x 删除指定的ACL权限
– b 删除所有的ACL权限
– d 设定默认ACL权限
– k 删除默认ACL权限
– R 递归设定ACL权限
– setfacl -m u:xiaolongge:rw test
– setfacl -m g:stu:rwx test - 最大有效权限mask:mask用来指定最大有效权限的。如果我给用户赋予了ACL权限,是需要和mask的权限“相与”才能得到用户的真正权限
– setfacl -m m:rx test - 删除ACL权限:setfacl -x u:lw test
- 删除文件的所有ACL权限:setfacl -b test
- 递归ACL权限: setfacl -m u:lw:rx -R test
- 权限溢出:ACL最大的问题,递归权限不可避免
- 默认ACL权限:默认ACL权限的作用是如果给父目录设定了默认ACL权限,那么父目录中所有新建的子文件都会继承父目录的ACL权限
– setfacl -m d:u:用户名:权限 目录名
sudo权限
- root 把本来只能超级用户执行的命令赋予普通用户执行
- sudo 的操作对象时系统命令
- 命令:visudo = vi /etc/sudoers.tmp
– root ALL=(ALL) ALL
– 用户名 被管理主机的地址=(可使用的身份) 授权命令(绝对路径)
– % wheel ALL=(ALL) ALL
– 组名 被管理主机的地址= (可使用的身份) 授权命令(绝对路径) - sudo -l 查看可以执行的sudo命令
- sudo /sbin/shutdown -r now
- 赋予修改密码的权限: user ALL=/usr/bin/passwd [A-Za-z]*, !/user/bin/passwd “”, !/usr/bin/passwd root
文件特殊权限
- SetUID
– 只有可执行的二进制程序才能设定SUID权限
– 命令执行者要对程序拥有x(执行)权限
– 命令制定者在执行改程序时获得该程序文件属主的身份(在执行程序的过程中灵魂附体为文件的属主)
– SetUID权限只在该程序执行过程中有效,也就是说身份改变只在程序执行过程中有效 - chmod 4755 文件名
- chmos u+s 文件名
// 检测系统中的SUID和SGID文件
#!/bin/bashfind / -perm -4000 -o -perm -2000 > /tmp/setuid.checkfor i in $(cat /tmp/setuid.check)do grep $i /root/suid.log > /dev/null if ["$?" != ""] then echo "$i isn't in listfile!" >> /root/suid_log_$(date+%F) fidone
- SetGID
- SetGID针对文件的作用
– 组身份升级为该所属组的身份
– 典型应用为:locate命令 /var/lib/mlocate/mlocate.db - SetGID针对目录的作用
– 普通用户必须对此目录拥有r和x权限,才能进入此目录
– 普通用户在此目录中的有效组会变成此目录的属组
– 若普通用户对此目录拥有w权限时,新建的文件的默认属组是这个目录的属组 - chmod 2755 文件名
chmod g+s 文件名
StickyBIT
- SBIT 粘着位作用
– 黏着位目前只对目录有效
– 普通用户对目录拥有w和x权限,即普通用户可以再次目录拥有写入权限
– 如果没有粘着位,因为普通用户拥有w权限,所以可以删除此目录下所有文件,包括其他用户建立的文件。一旦赋予了粘着位,除了root可以删除所有文件,普通用户就算拥有w权限,也只能删除自己建立的文件,但是不能删除其他用户建立的文件 - chmod 1755 目录名
- chmod o+t 目录名
- 取消粘着位:chmod 0777 目录名
- chmod o-t 目录名
不可改变位权限
- chattr [+-=] [选项] 文件或目录名
– +:增加目录
– -:删除目录
– =:等于某权限 - i(insert):如果对文件设置i属性,那么不允许对文件进行删除、改名,也不能添加和修改数据;如果对目录设置i属性,那么只能修改目录下文件的数据,但不允许建立和删除文件。
- a(append):如果对文件设置a属性,那么只能在文件中增加数据,但是不能删除也不能修改数据;如果对目录设置a属性,那么只允许在目录中建立和修改文件,但是不允许删除。
– lsattr 文件名
Linux日志
系统日志
- /var/log/messages 系统主日志文件
- /var/log/secure 认证、安全
- /var/log/dmesg 和系统启动相关
- access.log nginx nginx访问日志
- mysqld.log mysqld运行日志
- xferlog 和访问FTP服务器相关
服务管理
RPM包默认安装的服务
- 独立的服务
– 查看自启动的服务:chkconfig –list
– 常规端口:/etc/services
– 查看系统中开启的端口:netstat -tlunp
t 列出tcp数据
u 列出udp数据
l 列出正在监听的网络服务(不包含已经连接的网络服务)
n 用端口号显示服务,而不是服务名
p 列出该服务的进程ID(PID) - 启动服务:/etc/init.d/服务名 start|stop|status|restart
- service 服务名 start|stop|status|restart
- 开启自启动:chkconfig –level 2345 httpd on
- 关闭自启动:chkconfig httpd off
- 自启动:/etc/rc.d/rc.local
- 使用ntsysv命令自启动
- 基于xinetd服务
– 安装xinetd:yum -y install xintd
– 重启xinetd:service xinted restart
– /etc/xinetd.d/服务
源码包安装的服务
- 查看源码包服务:ls /usr/local
- 使用绝对路径:/usr/local/apache2/bin/apachectl start|stop
- 自启动:/etc/rc.local
- 让源码包服务被系统服务识别:ln -s /usr/local/apache2/bin/apachectl /etc/init.d/apache
- 让源码包服务能被chkconfig和ntsysv识别:
- vi /etc/init.d/apache
# chkconfig 35 86 76
# description:source package apache - chkconfig –add apache
进程管理
查看进程-ps命令和pstree命令
- ps aux 查看系统中所有进行,使用BSD操作系统格式
- ps -le 查看系统中所有进行,使用Linux标准命令格式
- 选项
–a:显示一个终端所有的进程,除了会话引线
–u:显示进程的归属用户及内存的使用情况
–x:显示没有控制终端的进程
–l:长格式显示,显示更加详细的信息
–e:显示所有进程,和-A作用一致
- pstree
–p 显示PID
–u 显示用户 - top -b -n 1 查看所有进程
杀死进程
- kill -l 查看可用的进程信号
- kill -HUB 进程号 / kill -l 进程号
- kill -9 进程号
- killall [选项][信号] 进程名 按照进程名终止进程
- 选项:
- pkill [选项][信号] 进程名 按照进程名终止进程
- 选项
– i:交互式,询问是否要杀死某个进程
– I:忽略进程名的大小写
–t 终端号:按照终端号踢出用户 - w 查看本机已经登录的用户
- pkill -9 -t pts/1
修改优先级
- ps -le
- nice [选项] 命令
nice命令可以给新执行的命令直接赋予NI值,但是不能修改已经存在的进程的NI值 - 选项
–n NI值:给命令赋予NI值 - nice -n -5 service httpd start
- renice [优先级] PID
renice命令是修改 已经存在进程的NI值的命令 - renice -10 2125
工作管理
工作管理方法
- top &
- top ctrl+z 放入后台暂停
- jobs [-l] 查看后台的命令
- fg %工作号 恢复到前台运行
- bg %工作号 恢复到后台运行
后台命令脱离终端
- 1.放入/etc/rc.local
- 2.使用系统定时任务
- 3.使用nohup命令
- nohup 命令 &
查看系统资源
- vmstat [刷新延迟 刷新次数]
- vmstat 1 3
- dmsg 开机时内核检测的信息
- dmsg | grep CPU
- free [-b|-k|-m|-g]
- cat /proc/cpuinfo 查看cpu信息
- utime 显示系统的启动和平均负载,也就是top命令的第一行。w命令也可以看到这个数据。
- uname [选项]
- 选项:
– a:查看系统所有相关信息
– r:查看内核版本
– s:查看内核名称 - file /bin/ls 查看系统的位数
- lsb_release -a 查看发型版本
- lsof [选项] 列出进程调用或打开的文件的信息
- 选项:
–c 字符串:只列出以字符串开头的进程打开的文件
–u 用户名:只列出某个用户的进程打开的文件
–p PID:列出某个PID进程打开的文件 - lsof | more
- lsof /sbin/init
- lsof -c httpd
iptables配置
- iptables -I INPUT -p tcp –dport 80 -j ACCEPT
- iptables -I INPUT -p tcp –dport 10:21 -j ACCEPT
- iptables -I INPUT -p ICMP -j ACCEPT
- iptables -A -p tcp -j ACCEPT
0 0
- linux学习笔记(1)
- LINUX命令学习笔记
- linux学习笔记(1)
- linux学习笔记(2)
- linux学习笔记(3)
- linux学习笔记
- linux学习笔记
- linux 学习笔记
- linux学习笔记二
- linux学习笔记
- linux学习笔记
- Linux学习笔记
- linux学习笔记
- linux学习笔记
- linux学习笔记
- LINUX 学习笔记(转)
- Linux学习笔记
- Linux 学习笔记
- Sql Server的执行计划
- C++ 对象数组释放造成内存泄漏
- 字符串匹配
- Snapcraft操作演示--教你如何snap一个应用
- 工厂模式
- Linux学习笔记
- Protostuff自定义序列化(Delegate)解析
- 图片转换为字节流,字节流转换为图片
- 关于ArcGIS Engine 开发:添加控件错误信息——创建组件**失败……您必须有许可证才能使用ActiveX控件
- cccam数控车床智能编程v3.0正式版
- 各种数据报头信息
- 《黑客与画家》读后感
- hdoj2054又见GCD(GCD最大公约数)
- js报错:Uncaught SyntaxError: Unexpected token ILLEGAL