#安装openssh。如果安装完成并且默认启用该服务,则可以通过ssh远程连接。
sudo apt-get 安装openssh-server
# 检查ssh服务状态
sudo 服务ssh 状态
# ssh服务重启命令
sudo 服务ssh 重新启动
# 编辑ssh服务的配置文件,可以修改服务端口、权限控制等。
sudo vim /etc/ssh/sshd_config ssh的sshd_config配置文件主要参数如下:
# 这是ssh服务的监听端口。在实际生产环境中,一般不使用默认的22端口。
端口22
#AddressFamily设置为any:默认ipv4和ipv6地址都可以连接
地址家庭任何
# ListenAddress用于设置sshd服务器绑定的IP地址。
# ListenAddress 192.168.0.231 表示仅监听IP 192.168.0.231 的SSH 连接
# ListenAddress 0.0.0.0 表示监听所有IPv4 SSH 连接
# ListenAddress : 表示监听所有IPv6 SSH 连接
# PermitRootLogin 设置root用户是否运行登录以及登录方式
允许根登录否
# LoginGraceTime 宽限登录时间,两分钟后无需输入密码,将自动注销。
登录宽限时间2m
#AllowUsers只允许某些用户登录(root用户能否登录取决于PermitRootLogin)
# 允许用户我的用户名
# 最高优先级,禁止某些用户登录
# 拒绝用户名1
# 允许登录的用户组
# 允许组mygroupname
# 禁止登录的用户组
# DenyGroups 组名1
# 设置sshd在用户登录时是否显示/etc/motd中的信息,可以添加欢迎信息。
打印模式
# ssh登录成功后是否显示上次登录信息
打印最后日志是
# ssh服务器会向客户端发送KeepAlive消息,以保证两者之间的连接正常。
# 这种消息可以检测死连接、不正确的连接关闭、客户端崩溃等异常情况。
# 当任一端死亡时,ssh 会立即知道,而不会出现僵尸程序。
TCPKeepAlive 是专门针对PermitRootLogin 选项,可以设置为以下值(without-password 也写为禁止密码),含义如下:
参数类别是否允许ssh 登录登录方式交互式shellyes 允许无限制无限制without-password 允许无限制除密码强制-commands-only 允许只允许密钥只允许授权命令不允许N/AN/A :010 -1010
2. SSH保活的几种方法
SSH总是被强行中断,导致效率低下。可以在服务器端进行配置,让服务器每30秒向客户端发送一个keep-alive数据包来维持连接: sudo vim /etc/ssh/sshd_config
添加以下内容:
客户端活动间隔30
ClientAliveCountMax 60 然后重启本地ssh: sudo service ssh restart
第一行配置允许服务器每30秒向客户端发送一个keep-alive数据包以维持连接;第二行配置表示如果连续发送keep-alive包的次数达到60次而客户端仍然没有响应,则服务器的sshd将被断开。打开连接。如果什么都不做,这个配置可以保持连接打开30s*60,即30分钟。
2.1 配置服务器端
如果服务器没有权限配置,或者无法配置,可以配置客户端ssh,让客户端发起的所有会话保持连接: sudo vim /etc/ssh/ssh_config
添加以下内容:
服务器活动间隔30
ServerAliveCountMax 60 然后重启本地ssh: sudo service ssh restart
本地ssh 每30 秒向服务器sshd 发送一次keep-alive 数据包。如果连续发送60次,服务器仍然没有响应并断开连接。
2.2 配置客户端
如果需要在多个窗口中打开同一个服务器连接,可以尝试添加~/.ssh/config,添加以下两行:
控制大师自动
ControlPath ~/.ssh/connection-%r@%h:%p 然后重启本地ssh: sudo service ssh restart
配置后,第二个连接共享第一个建立的连接以加快该过程。
如果你希望每次建立SSH连接时,这个连接都会维持4小时,并且在退出服务器后仍然可以重复使用,你需要设置:
控制持续4h
最后,一个~/.ssh/config文件配置示例如下:
主持人*
服务器活动间隔3
服务器活动计数最大20
TCPKeepAlive 否
控制大师自动
ControlPath ~/.ssh/connection-%r@%h:%p
控制持续4h
用户zfb
2.3 共享ssh连接
ssh -o ServerAliveInterval=60 user@sshserver
2.4 ssh连接的同时保活
经常需要通过SSH 远程登录Linux 服务器并运行一些需要较长时间才能完成的任务,例如训练数据集、ftp 传输等。通常必须打开远程终端窗口才能完成每个此类任务,因为它们执行时间太长,您必须等待它们完成执行。在此期间不能关闭窗口或断开连接,否则任务会被kill
使用screen命令可以实现会话恢复、会话共享、多窗口等功能。
只要屏幕本身没有终止,就可以恢复其中运行的会话。这对于远程登录的用户特别有用,这样即使网络连接中断,用户也不会失去对已打开的命令行会话的控制。只需再次登录主机并执行screen -r 即可恢复会话。
另外在暂时离开时,也可以执行detach命令切换到后台,同时保证里面的程序正常运行。
您还可以让一个或多个用户从不同的终端多次登录会话并共享会话的所有功能(例如查看完全相同的输出)。它还提供了窗口访问权限的机制,并可以使用密码保护窗口。
所有会话都独立运行并拥有自己的编号、输入、输出和窗口缓冲区。用户可以通过快捷键在不同的窗口之间进行切换,并且可以自由地重定向每个窗口的输入和输出。它实现了基本的文本操作,如复制、粘贴等;它还提供类似滚动条的功能来查看窗口状况的历史记录。还可以对窗口进行分区和命名,并且可以监视后台窗口活动。
具体用法如下:
# 启动一个名为test_scr 的屏幕。这时候你就会看到创建新会话的动作。
屏幕-S test_scr
# 您可以在这个新窗口中运行任何命令。即使命令行不断刷新输出,您也可以执行下一步操作。
# 即:按Ctr+A,然后按D。这将使test_scr进入后台并返回到上一个窗口。
Ctrl+AD
# [与45197.test_scr 分离]
# 列出所有屏幕
屏幕-ls
#:上有一个屏幕
# 45197.test_scr(2020 年7 月17 日14:39:09)(已分离)
# 1 套接字位于/run/screen/S-zfb。
# 此时退出不会影响。您只需重新登录并输入以下命令即可。
# 也可以是screen -r 45197
屏幕-r test_scr
# 删除某个屏幕,假设是test_scr;也可以切换到test_scr的屏幕,快捷键Ctrl+A K
screen -S test_scr -X 退出
# 死机状态下清屏
屏幕擦拭
# 强制退出其他用户正在使用的屏幕窗口(防止某个用户断开连接占用终端,导致其他用户无法使用)
screen -D -r test_scr
2.5 screen命令使用
3. Ubuntu用户管理
创建用户,创建用户主目录,并创建与用户同名的组(用户名为username)
sudo adduser 用户名
系统将提示您设置密码。如果出现其他提示,只需按Enter 键即可。
如果需要让该用户拥有root权限,修改root用户下的/etc/sudoers文件:
root@ubuntu:~# sudo vim /etc/sudoers
修改文件如下:
# 用户权限规范
根全部=(全部)全部
username ALL=(ALL) ALL 保存退出,username 用户将拥有root权限
或sudo usermod -a -G sudo 用户名
3.1 创建用户
从当前用户切换到用户名的命令:su username
也可以使用命令从普通用户切换到root用户:sudo su
切换用户时,如果切换用户后想使用新用户的工作环境,可以在su和用户名之间添加,例如:su - root
终端提示符$代表普通用户;代表超级用户,即root用户
在终端输入exit或logout或者使用快捷键Ctrl+d,可以退回到原来用户
3.2 切换用户
修改用户名username的启动登录密码:sudo passwd username
修改root密码(默认root无密码,第一次执行时创建密码): sudo passwd root
3.3 修改用户密码
仅禁用root,但root密码仍然保存:
sudo passwd -l 根
然后使用su root切换root用户,发现认证失败。
启用root 登录:
sudo passwd -u 根
3.4 禁用和启用root登录
在root用户下创建一个文件夹,创建一个新的用户组,并将原来的用户添加到这个新组中。假设新建的用户组为share_grp,新建的共享文件夹目录为/home/data_share/(也可以是/media/data_share),需要互相共享的用户为user1和user2。每个用户都可以使用cd /home/data_share/来访问该文件夹的内容。具体步骤如下:
首先将当前帐户切换为root帐户,然后创建文件夹mkdir /home/data_share/,然后创建新的用户组share_grp。使用命令sudo groupadd share_grp 更改文件夹所属组sudo chgrp share_grp /home/data_share 更改文件夹权限sudo chmod 770 /home/data_share 确保子文件夹也具有相同的权限sudo chmod +s /home/data_share为用户1添加附属组,且不影响用户原有组。 sudo usermod -a -G share_grp user1 对用户2 执行相同的操作。使用命令sudo usermod -a -G share_grp user2。此时,两个用户都可以访问目录/home/data_share/。另外,查看用户组相关命令如下:
groups:查看当前用户的组cat /etc/group:查看本地机器上的所有用户和组。如果不想继续共享,可以在root账户下使用以下命令删除用户1和用户2所属的组(原组不受影响)
sudo usermod -G "" user1
sudo usermod -G "" user1
sudo groupdel share_grp
3.5 多用户共享目录
chown 命令用于设置文件(或文件夹)的所有者和文件关联组。该文件支持通配符。只有超级用户可以执行该命令。使用方法如下: # -R表示递归执行,test是当前目录下的文件夹,前面的zfb代表用户名,后面的zfb代表用户组
# 该命令会将test目录及其子目录下所有文件的属主更改为zfb,所属组也更改为zfb
sudo chown -R zfb:zfb testchgrp 命令用于更改文件(或文件夹)所属的组。普通用户可以执行该命令,如:# -R 表示递归执行,test 是当前目录下的文件夹,mygrp1 表示用户组
# 该命令会将test目录及其子目录中所有文件的组更改为mygrp1
chgrp -R mygrp1 testchmod 命令用于更改文件(或文件夹)的权限。普通用户可以执行该命令,如:# -R 表示递归执行,test是当前目录下的文件夹
# 该命令会将test目录及其子目录下的所有文件的权限改为777。这是一种使用数字设置权限的方法。
#777这三个数字分别对应:文件所有者u的权限、与所有者同组的用户g的权限、其他用户o的权限
# 7是十进制表示,原来的二进制是111,对应:读r,写w,执行x; 1表示允许,0表示禁止
chmod -R 777 测试
# chmod命令也可以使用字母来设置权限
# u 代表文件所有者; g代表文件所属的组; o 代表其他用户; a代表系统的所有用户
# r表示可以读取; w表示可写; x表示可以执行
# + 表示添加某个(多个)权限; - 指删除某个(多个)权限;=表示撤销所有原有权限,只设置某一个(多个)权限
# 例如:给文件添加可执行权限。如果不指定用户,则默认为系统中的所有用户。
# 以下命令相当于chmod a+x stop.sh
chmod +x stop.sh
# 例如:为文件所有者和同组用户添加写权限,为其他用户删除执行权限
chmod ug+x,o-x test.txt
# 例如:撤销原来的文件权限,只设置该文件的读写权限
chmod u=rw name.txt
3.6 文件系统设置所有者
使用以下命令:
sudo -u www-data stat /home/ubuntu/frp/log
如果您有权限,输出类似于:
File: /home/ubuntu/frp/log/
大小: 4096 块: 8 IO 块: 4096 目录
设备: fc01h/64513d Inode: 529293 链接: 2
Access: (0777/drwxrwxrwx) Uid: (500/ubuntu) Gid: (500/ubuntu)
访问: 2020-09-28 15:56:40.902601841 +0800
修改: 2020-09-28 16:32:40.728799201 +0800
变更: 2020-09-28 16:32:40.728799201 +0800
Birth: - 否则显示:
stat: 无法stat "/home/ubuntu/frp/log/": 权限被拒绝
3.7 测试某个用户是否可以访问文件夹
查看所有用户列表
cat /etc/passwd|grep -v nologin|grep -vhalt|grep -v shutdown|awk -F":" "{ print $1"|"$3"|"$4 }"|more
查看当前登录的用户
w
检查您登录的用户名
瓦阿米
4. 查看当前活跃的用户
将命令组合重命名,写入.bashrc文件中,方便使用:先vi ~/.bashrc,然后将以下内容写入文件末尾
别名maxmem="ps -aux|head -1;ps -aux |排序-k4nr |头"
# ps -aux 会显示所有进程,userid,x指所有程序
# ps -aux|head -1 表示只保留删除结果的第一行,即表头。
# sort -k4nr 命令:r表示对结果进行倒序排序,n表示按数值大小排序
# -k4 是对第4列的内容进行排序
# maxmem -4 表示显示4条结果
5. 查看当前占据内存最多的进程信息
对于桌面版Ubuntu,只需打开程序列表中的图标,选择启动应用程序,启动应用程序图标,根据提示输入路径即可。
6. ubuntu设置开机自启程序
远程控制软件Sunflower似乎不支持Ubuntu原来的gdm3桌面。具体表现为:使用Windows在服务器的Ubuntu系统上远程调试时,总是出现连接断开的情况;但反过来,它是可以控制的。因此安装lightdm 来替换默认的桌面显示管理器:
sudo apt-get 更新
sudo apt-get 升级
# 安装过程中会提示选择默认显示管理器,选择lightdm即可。
sudo apt install lightdm 然后重启设备,然后再次测试,连接正常。
如果需要卸载lightdm并再次使用gdm3,只需输入以下命令:
# 查看当前使用的显示管理器
猫/etc/X11/default-display-manager
# 重新选择gdm作为显示管理器然后重启
sudo dpkg-重新配置gdm3
# 卸载lightdm
sudo apt-get --purge remove lightdm
7. 修改ubuntu显示管理器为lightdm
nohup 表示忽略SIGHUP 信号,一般用在普通命令语句之前。如果用户关闭shell,使用nohup启动的进程仍然存在(因为关闭终端会发送SIGHUP信号,而nohup不受SIGHUP信号影响)。如果不重定向nohup 命令的输出,输出将附加到当前目录中的nohup.out 文件中。如果当前目录中的nohup.out 文件不可写,则输出将重定向到$HOME/nohup.out 文件。
输出重定向:当程序在后台运行时,可以将输出重定向到一个文件,相当于一个日志文件,记录运行过程中的输出。例如nohup 命令out.txt 21 命令的意思是
将命令的输出重定向到out.txt文件,即输出内容不打印在屏幕上。 0 stdin(标准输入), 1 stdout(标准输出), 2 stderr(标准错误) 21 是将标准错误(2)重定向到标准输出(1),并将标准输出(1)然后重定向到out.txt文件,表示在后台运行,一般在普通命令语句之后使用。即使用户使用Ctrl+C,启动的程序仍然会运行(因为它不受SIGINT信号的影响)
因此可以使用以下命令来实现类似守护进程的功能:
nohup 命令out.file 21
8. nohup与的使用
Linux 提供fg 和bg 命令来调度正在运行的任务。如果你发现某个程序在前台运行时间较长,但又需要做其他事情,可以使用Ctrl+Z暂停该程序,然后就可以看到系统提示:
[1]+ 已停止/root/bin/rsync.sh
然后可以安排该程序在后台执行,以便前台可以执行其他任务。该命令的运行效果与在命令后添加符号相同。两者都是在系统后台执行(bg后面的数字是作业号)
背景1
# 终端回显如下
# [1]+ /root/bin/rsync.sh 使用jobs 命令查看正在运行的任务(只有当前终端中生效的任务可见,关闭终端重新打开就看不到):
职位
# 终端回显如下
# [1]+ 运行/root/bin/rsync.sh 如果要将任务带回前台,可以使用
图1
# 终端回显如下
# /root/bin/rsync.sh 这样就只能在终端等待任务完成了。
9. 命令的挂起和前后台切换
不安装第三方工具有两种方法:
使用scp命令:例如scp -P 8899 -r root@45.67.89.12:/root/test/./Desktop/命令的意思是递归下载服务器的/root/test/文件夹到本地./Desktop/文件夹。 8899 为ssh 端口,默认为22。使用rsync 命令(支持断点续传):例如rsync -avzP --rsh="ssh -p 8899" root@45.67.89.12:/root/test/./Desktop命令的意思是下载服务器的/root/test/文件夹到本地的./Desktop/文件夹。 8899 是ssh 端口。默认值为22。使用脚本下载Google Drive 文件。使用方法是:
卷曲gdrive.sh | bash -s https://drive.google.com/file/d/0B4y35FiV1wh7QWpuVlFROXlBTHc/view
10. 远程收发文件
11. find命令
find 命令可以在指定目录及其子目录中搜索具有指定扩展名的文件。如下所示,它在当前目录及子目录中搜索JPG文件并将其移动到当前目录:
寻找。 -name "*.jpg" -exec mv {} ./;
寻找。表示在当前目录及其子目录中搜索
-name "*.jpg" 表示仅搜索扩展名为JPG 的文件
-exec后面是bash命令,表示对文件的操作
{} 指的是找到的每个文件
;你需要添加;在bash 命令的末尾,需要转义。
11.1 查找文件
find命令也可以用来查找符合条件的目录。只需添加参数-type d即可指定搜索类型为目录。如下图,在当前目录及其子目录中搜索所有以mat结尾的文件夹,并将a.py复制到所有找到的文件夹中(将单个文件复制到多个文件夹中)
寻找。 -type d -name "*_mat" -exec cp a.py {} ;
流程如下:
/测试树。
a.py
垫子目录
18_垫
1_垫
2_垫
45_垫
9_垫
6个目录,1个文件
/测试查找。 -type d -name "*_mat" -exec cp a.py {} ;
/测试树。
a.py
垫子目录
18_垫
a.py
1_垫
a.py
2_垫
a.py
45_垫
a.py
9_垫
a.py
6个目录,6个文件
11.2 查找目录
12. swap分区操作
系统默认为
有了swap分区,但是运行某些程序很耗内存,想临时添加swap分区大小: # 创建交换分区的文件:增加64G=65536M大小的交换分区,则命令写法如下 # 其中的bs等于想要的块大小,of是交换文件的名称和位置 # 以下命令如果提示权限不足,加上sudo dd if=/dev/zero of=/home/swap bs=1M count=65536 # 设置交换分区文件,建立swap的文件系统 mkswap /home/swap # 如果提示 swapon: /home/swap: insecure permissions 0644, 0600 suggested. chmod -R 0600 /home/swap # 立即启用交换分区文件,swapon -p 2 /home/swap可以设置该swap的优先级 swapon /home/swap # 如果还需要使系统开机时自动启用,在文件/etc/fstab中添加一行: # /home/swap swap swap defaults 0 0此时可以查看分区大小是否添加成功(系统原始的交换空间是swap分区,大小为64G): zfb@myServer:~$ free -m total used free shared buff/cache available Mem: 128804 77303 590 78 50910 50386 Swap: 126570 387 126183 zfb@myServer:~$ cat /proc/swaps Filename Type Size Used Priority /dev/sda2 partition 62499836 397288 -2 /home/swap file 67108860 0 -3 zfb@myServer:~$这里的cat /proc/swaps命令等价于swapon -s,在使用多个swap分区或者文件的时候,还有一个优先级的概念,值越大优先级越高(-1的优先级最高,-1表示在安装系统时创建的)。设置swap分区时未指定优先级,则将优先级分配为-1,后添加的swap则依次为-2,-3;而用户指定优先级时必须以正数表示,也就是说用户指定的优先级必然高于系统优先级 内核在使用swap空间的时候总是先使用优先级高的空间,后使用优先级低的;如果把多个swap空间的优先级设置成一样的,那么两个swap空间将会以轮询方式并行进行使用;如果两个swap放在两个不同的硬盘上,相同的优先级可以起到类似RAID0的效果12.2 删除自己添加的swap文件
按照以下操作: # 关闭指定swap,swapoff -a表示关闭所有 swapoff /home/swap # 如果增加分区有设置开机自动挂载,就需要删除或者注释文件/etc/fstab中的对应行 # 正常删除文件即可 rm /home/swap12.3 设置swap的使用情况
按照如下方法设置即可: # 查看系统默认的 swappiness 值 # swappiness=0 表示最大限度使用物理内存 # swappiness=100 表示积极的使用swap分区 cat /proc/sys/vm/swappiness # 修改swappiness值为10,临时性的修改,重启系统后会恢复默认值 sudo sysctl vm.swappiness=10 # 永久修改swappiness,打开文件/etc/sysctl.conf # 在文件最后添加一行 vm.swappiness = 10 sudo vi /etc/sysctl.conf # 使修改立即生效 sudo sysctl -p13. 查看历史登录记录
13.1 使用last命令
使用命令last即可列出所有相关信息 zfb@myServer:~$ last zfb pts/2 127.0.0.1 Sat Sep 5 12:29 still logged in zfb pts/1 :pts/0:S.0 Sat Sep 5 09:23 still logged in zfb pts/1 :pts/0:S.0 Thu Sep 3 22:38 - 22:38 (00:00) zfb pts/1 127.0.0.1 Wed Jul 8 17:20 - 17:21 (00:00) user1 pts/0 127.0.0.1 Wed Jul 8 17:07 - 17:21 (00:13) user2 pts/0 127.0.0.1 Wed Jul 8 15:49 - 15:49 (00:00) zfb pts/0 127.0.0.1 Wed Jul 8 15:42 - 15:45 (00:03) reboot system boot 4.15.0-108-gener Wed Jul 8 15:40 - 12:00 (10+20:20) zfb pts/2 127.0.0.1 Wed Jul 8 15:19 - 15:20 (00:00) user2 :0 :0 Wed Jul 8 15:00 - down (00:38) reboot system boot 4.15.0-108-gener Wed Jul 8 22:09 - 14:48 (-7:21) reboot system boot 4.15.0-108-gener Wed Jul 8 21:28 - 21:29 (00:00) wtmp begins Wed Jul 8 21:28:47 201913.2 使用awk命令
13.2.1 awk命令详解
假定test.txt文件内容如下: Aug 28 19:38:01 localhost CRON[12375]: pam_unix(cron:session): session closed for user root Aug 28 19:39:01 localhost CRON[12511]: pam_unix(cron:session): session opened for user root by (uid=0) Aug 28 19:39:01 localhost CRON[12511]: pam_unix(cron:session): session closed for user root Aug 28 19:39:13 localhost sshd[12493]: Invalid user admin from 25.67.84.30 port 1345 Aug 28 19:39:14 localhost sshd[12493]: pam_unix(sshd:auth): check pass; user unknown Aug 28 19:39:16 localhost sshd[12493]: Failed password for invalid user admin from 25.67.84.30 port 1345 ssh2 Aug 28 19:39:32 localhost sshd[12493]: Disconnecting invalid user admin 25.67.84.30 port 1345: Change of username not allowed Aug 28 19:39:44 localhost sshd[12596]: pam_unix(sshd:auth): check pass; user unknown Aug 28 19:40:27 localhost sshd[12679]: Failed password for root from 34.56.78.90 port 6666 ssh2 Aug 28 19:40:31 localhost sshd[12679]: Failed password for root from 78.90.12.34 port 8888 ssh2 Aug 28 19:40:53 localhost sshd[12741]: Invalid user admin from 12.34.56.78 port 3810 Aug 28 19:40:56 localhost sshd[12741]: Failed password for invalid user admin from 12.34.56.78 port 3810 ssh2 Aug 28 19:40:58 localhost sshd[12741]: Disconnecting invalid user admin 12.34.56.78 port 3810 Aug 28 19:41:01 localhost CRON[1316]: pam_unix(cron:session): session opened for user root by (uid=0) Aug 28 19:41:01 localhost CRON[2316]: pam_unix(cron:session): session closed for user root Aug 28 19:41:10 localhost sshd[3328]: Invalid user user from 12.34.56.78 port 9999 Aug 28 19:41:11 localhost sshd[4328]: pam_unix(sshd:auth): check pass; user unknown Aug 28 22:34:58 localhost sshd[18689]: Failed password for root from 199.200.201.202 port 33667 ssh2 Aug 28 22:56:22 localhost sshd[18560]: Failed password for invalid user pi from 18.19.20.21 port 22222 ssh2 Aug 28 22:56:23 localhost sshd[18561]: Failed password for invalid user pi from 78.56.34.21 port 41568 ssh2 Aug 28 22:06:48 localhost sshd[18943]: Failed password for invalid user ubnt from 66.88.99.44 port 33444 ssh2 Aug 28 22:06:48 localhost sshd[18944]: Failed password for root from 193.116.1.108 port 54360 ssh2 Aug 28 22:06:48 localhost sshd[18945]: Failed password for root from 193.116.1.108 port 54362 ssh2 Aug 28 22:06:49 localhost sshd[18942]: Failed password for root from 193.116.1.108 port 54358 ssh2 Aug 28 22:11:46 localhost sshd[18589]: Failed password for root from 18.19.12.20 port 6688 ssh2 Aug 28 22:24:08 localhost sshd[18213]: Failed password for root from 185.2.99.114 port 9988 ssh2如下所示是一个常用的awk命令的语法 awk "{print $1, $4}" test.txt需要注意的是,awk后面的语句{print $1, $4}必须用单引号括起来(这表明是行匹配模式,即对文件中匹配到的每一行执行操作print $1, $4),而且awk默认以空格对每一行进行分割并执行对应语句 awk的语句完整流程为BEGIN{print "这是匹配前执行的,一般是表头"}{print NR,$1,$2}END{printf("统计完毕")},BEGIN和END语句可以省略 awk的条件语句{if($1>3) print $1;else if($2==6) print $4;else print "hh"} OFS ORS OFMT等可以在BEGIN模块设置,例如awk "BEGIN{FS=",";OFMT="%.3f"} {print $1,$2}" test.txt print语句内部支持+-*/等基础运算printf("%d--%dn", $1,$2)命令与C语言的使用方法类似如果要使用逗号进行行分割则awk -F, "{print $1, $4}" test.txt$0表示整行数据,$1表示每行的第一部分(按照规则对行分割后的集合),称为第一个字段,以此类推;另外,匹配到的第一行称为第一条记录NR表示当前行的数字(即这在test.txt中是第几行),NF表示当前行的长度,FNR表示当前行的数字(即这在匹配记录中是第几行),FILENAME表示当前文件的名称,FS表示分隔符(把一行数据分割成$1到最后)创建变量a并设置a的值,则使用awk -va=1 "{print $2,$2+a}" test.txtOFS设置所有输出字段分隔符,如果要使得在print时候$i之间的默认空格改为其他分割则使用awk -va=1 "{print $2,$2+a}" OFS=", " test.txt设置某两个字段之间的连接符,使用代码awk "{print NR, $1"-"$2, $11}" test.txt,则字段1和2输出时使用连接ORS设置所有输出记录分隔符,如果要使得在print时候不同行之间的默认空格改为其他分割则使用awk -va=1 "{print $2,$2+a}" ORS="nn " test.txtOFMT设置所有小数的显示格式,默认为%.6g,若显示3位小数则awk "{print NR, $11, $13":"$15, 1/2}" OFMT="%.3f"例如执行命令grep "Failed password for invalid user" test.txt | awk "BEGIN{printf("%-10s %-10s %-20sn", "number", "user", "IP:Port")}{printf "%-10s %-10s %-20sn", FNR, $11, $13":"$15}END{printf("搜索结束,共找到%d条记录", FNR)}" 则输出如下内容,使用":"指定$13和$15字段的连接,如果用,则使用默认字段连接符(空格): number user IP:Port 1 admin 25.67.84.30:1345 2 admin 12.34.56.78:3810 3 pi 18.19.20.21:22222 4 pi 78.56.34.21:41568 5 ubnt 66.88.99.44:33444 搜索结束,共找到5条记录13.2.2 awk过滤并输出记录
查看系统的登陆失败的用户及IP信息(只输出ssh连接时的用户名不存在的情况): sudo grep "Failed password for invalid user" /var/log/auth.log | awk "BEGIN{printf("%-10s %-10s %-20sn", "number", "user", "IP:Port")}{printf "%-10s %-10s %-20sn", FNR, $11, $13":"$15}END{printf("搜索结束,共找到%d条记录", FNR)}" 输出示例: number user IP:Port 1 admin 25.67.84.30:1345 2 admin 12.34.56.78:3810 3 pi 18.19.20.21:22222 4 pi 78.56.34.21:41568 5 ubnt 66.88.99.44:33444 搜索结束,共找到5条记录查看所有登陆失败的信息: # 首先从log文件提取出所有包含Failed password for字符串的行作为awk的输入 # 然后输出一行表头,并开始执行行匹配 # match函数的第二个参数是正则表达式(用//包围起来),如果未找到,返回0 # 有如下三种情况,前两个分别对应awk里面的if命令,第三种情况被过滤了 # Aug 28 22:11:46 localhost sshd[18589]: Failed password for root from 18.19.12.20 port 6688 ssh2 # Aug 28 22:56:22 localhost sshd[18560]: Failed password for invalid user pi from 18.19.20.21 port 22222 ssh2 # Sep 16 17:29:04 localhost sudo: ubuntu : TTY=pts/0 ; PWD=/home/ubuntu ; USER=root ; COMMAND=/bin/grep : Failed password for /var/log/auth.log # 因为在执行awk的同时会在auth.log生成一条记录如下,所以需要if(length($13)>4)这个判断 # Sep 16 17:10:31 localhost sudo: ubuntu : TTY=pts/0 ; PWD=/home/ubuntu ; USER=root ; COMMAND=/bin/grep Failed password for /var/log/auth.log sudo grep "Failed password for" /var/log/auth.log | awk "BEGIN{printf("%-10s %-10s %-20sn", "number", "user", "IP:Port")}{if(match($11, /./)!=0) printf "%-10s %-10s %-20sn", FNR, $9, $11":"$13;else if(length($13)>4) printf "%-10s %-10s %-20sn", FNR, $11, $13":"$15}END{printf("搜索结束,共找到%d条记录n", FNR)}"输出示例: number user IP:Port 1 admin 25.67.84.30:1345 2 root 34.56.78.90:6666 3 root 78.90.12.34:8888 4 admin 12.34.56.78:3810 5 root 199.200.201.202:33667 6 pi 18.19.20.21:22222 7 pi 78.56.34.21:41568 8 ubnt 66.88.99.44:33444 9 root 193.116.1.108:54360 10 root 193.116.1.108:54362 11 root 193.116.1.108:54358 12 root 18.19.12.20:6688 13 root 185.2.99.114:9988 搜索结束,共找到13条记录注意:此命令也可以写成脚本形式 # 创建awk脚本文件并写入内容 vim sshinfo.awk # 授予执行权限 chmod +x sshinfo.awk # 执行命令,对于CentOS系统为/var/log/secure文件 sudo grep "Failed password for" /var/log/auth.log | ./sshinfo.awksshinfo.awk的文件内容如下: #! /usr/bin/awk -f BEGIN{ printf("%-10s %-10s %-20sn", "number", "user", "IP:Port") } { if(match($11, /./)!=0) printf "%-10s %-10s %-20sn", FNR, $9, $11":"$13; else if(length($13)>4) printf "%-10s %-10s %-20sn", FNR, $11, $13":"$15 } END{ printf("搜索结束,共找到%d条记录n", FNR) }查看系统的登陆成功的用户及IP信息: sudo grep "Accepted password for" /var/log/auth.log | awk "BEGIN{printf("%-10s %-10s %-20sn", "number", "user", "IP:Port")}{printf "%-10s %-10s %-20sn", FNR, $11, $13":"$15}END{printf("搜索结束,共找到%d条记录", FNR)}" 输出示例: number user IP:Port 1 zfb 11.11.11.11:8888 2 zfb 11.11.11.11:8888 3 zfb 11.11.11.11:8888 4 root 11.11.11.11:8888 搜索结束,共找到4条记录查看系统登陆失败的次数及对应的IP: sudo grep "Failed password for" /var/log/auth.log | awk "{if(match($11, /./)!=0) print $11}" | sort | uniq -c | sort -nr | more14. 使用FTP下载文件
FTP(文件传输协议)是一个较老且最常用的标准网络协议,用于在两台计算机之间通过网络上传/下载文件。它通过用户凭证(用户名和密码)传输数据,没有进行加密。它是一个8位的客户端-服务器协议,能操作任何类型的文件而不需要进一步处理,就像MIME或Unicode一样。但是,FTP有着极高的延时,这意味着,从开始请求到第一次接收需求数据之间的时间,会非常长;并且不时的必须执行一些冗长的登录进程 一般运行在20和21两个端口。端口20用于在客户端和服务器之间传输数据流,而端口21用于传输控制流,并且是命令通向ftp服务器的进口。当数据通过数据流传输时,控制流处于空闲状态。而当控制流空闲很长时间后,客户端的防火墙会将其会话置为超时 FTP URL的格式在RFC 1738指定,格式为:ftp://[user[:password]@]host[:port]/url-path 首先确保系统已经安装ftp命令: sudo apt-get install ftp 此ftp命令的使用方法为,在终端输入以下命令(域名或IP地址或完整FTP网址都可以): ftp ftp.ngdc.noaa.gov 一般公开的FTP资源下载站点的用户名都是anonymous,密码是空,登录成功后即可打开交互终端 [zfb@myServer ~]# ftp ftp.ngdc.noaa.gov Connected to ftp.ngdc.noaa.gov (140.172.190.215). 220- ----- Notice ----- 220- 220- Questions/Problems should be directed to ngdc.webmaster@noaa.gov 220 Name (ftp.ngdc.noaa.gov:root): anonymous 331 Please specify the password. Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp>ls 227 Entering Passive Mode (140,172,190,215,188,178). 150 Here comes the directory listing. -rw-rw-r-- 1 ftp ftp 1516 Feb 04 2016 INDEX.txt -rw-rw-r-- 1 ftp ftp 3766 Feb 09 2018 README.txt -rw-rw-r-- 1 ftp ftp 9036 Feb 04 2016 ftp.html drwxrwsr-x 11 ftp ftp 11 Dec 19 2017 geomag -rw-r--r-- 1 ftp ftp 53 Jul 27 2010 google12c4c939d7b90761.html lrwxrwxrwx 1 ftp ftp 8 Aug 01 2011 index.html ->ftp.html 226 Directory send OK. ftp>cd geomag 250 Directory successfully changed. ftp>ls 227 Entering Passive Mode (140,172,190,215,74,181). 150 Here comes the directory listing. drwxrwxr-x 10 ftp ftp 12 Jul 08 2016 Access_Tools drwxrwxr-x 4 ftp ftp 9 Jul 14 2008 Aeromag 226 Directory send OK.在该交互窗口使用命令lcd /home/zfb/hh/表示设置下载远程FTP服务器的文件默认保存在本机的/home/zfb/hh/目录 在该交互窗口使用命令mget *表示下载当前目录下的所有文件,忽略所有子文件夹 在该交互窗口使用命令prompt off表示关闭下载提示批量遍历下载FTP站点指定目录下的所有数据: wget -r -nH -P/home/zfb/hh/ ftp://ftp.ngdc.noaa.gov/ionosonde/mids11/GR13L/individual/2019/* --ftp-user=anonymous --ftp-password=15. 切割日志文件
可以分为以下两种: 使用logrotate命令:见教程切割nginx日志文件:见教程16. 设置静态IP
有以下两种方法: 1.方法一:系统安装有GUI。打开设置-->网络,查看哪一个是当前正在使用的网络连接,点击该条右侧的设置(齿轮图标),弹出对话框。详细信息页面会显示当前的ip(例如:192.168.10.55)、网关路由地址(例如:192.168.10.254)、所有的DNS地址(例如:114.114.114.114,8.8.8.8),需要记录下来,方便后期修改。然后点击IPv4选项 IPv4方式:手动地址:共有三格。第一格填写自己需要设置的静态ip地址,例如写为192.168.10.56(也可设置为与之前DHCP方式分配的IP一致,即192.168.10.55);第二格填写子网掩码,一般是255.255.255.0(可以通过方法二的步骤核实);第三格填写网关地址192.168.10.254DNS:填写之前看到的即可,如114.114.114.114,8.8.8.8然后点击右上角应用,如果弹出输入密码则按要求输入即可。最后,关闭再打开网络即可应用成功2.方法二:在终端窗口修改。Ubuntu 17.10 网络管理引入了一个新的工具,用来配置ip地址,本教程只适合此版本及更新版本(旧版本如ubuntu 16.04不支持)。具体步骤如下: 查看并记录相关信息(也可使用方法一来查看):# 安装网络工具库 sudo apt-get install net-tools # (1)查看当前正在使用的网卡信息 ifconfig -a # 该命令会返回所有网卡信息,可通过查看每一条信息是否包含inet条目 # 且inet后面跟着的地址不是127.0.0.1 # 排除法即可找到当前使用的网卡,最前面是网卡名称,例如 # enp0s37f2: flags=4163mtu 1500 # inet 192.168.10.55 netmask 255.255.255.0 broadcast 192.168.10.255 # inet6 fe80::cdea:a610:64f0:bed2 prefixlen 64 scopeid 0x20# ether e3:aa:5e:6e:53:01 txqueuelen 1000 (以太网) # RX packets 44518 bytes 7552410 (7.5 MB) # RX errors 0 dropped 0 overruns 0 frame 0 # TX packets 40667 bytes 51864207 (51.8 MB) # TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 # device interrupt 16 memory 0xef300000-ef320000 # 记录: 网卡名称为enp0s37f2 当前ip地址为192.168.10.55 子网掩码为255.255.255.0 # (2)查看网关路由地址 route -n # 该命令输出的第一条(目标为0.0.0.0)的网关即为所需的地址,记录网关为192.168.10.254 # 内核 IP 路由表 # 目标 网关 子网掩码 标志 跃点 引用 使用 接口 # 0.0.0.0 192.168.10.254 0.0.0.0 UG 20100 0 0 enp0s37f2 # 169.254.0.0 0.0.0.0 255.255.0.0 U 1000 0 0 enp0s37f2 # 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0 # 192.168.10.0 0.0.0.0 255.255.255.0 U 100 0 0 enp0s37f2 # 也可使用traceroute命令来查找网关 traceroute www.baidu.com # 只看该命令的前两条输出即可,记录网关地址为192.168.10.254 # traceroute to www.baidu.com (14.215.177.38), 30 hops max, 60 byte packets # 1 _gateway (192.168.10.254) 0.392 ms 0.379 ms 0.372 ms # 2 * * * # (3)查看DNS记录 systemd-resolve --status # 从该命令输出中找到自己用的网卡 # Link 2 (enp0s37f2) # Current Scopes: DNS # LLMNR setting: yes # MulticastDNS setting: no # DNSSEC setting: no # DNSSEC supported: no # DNS Servers: 114.114.114.114 # 8.8.8.8 # DNS Domain: ~. # 记录DNS 114.114.114.114, 8.8.8.8创建配置文件:sudo vim /etc/netplan/01-network-manager-all.yaml 文件内容如下:network: ethernets: # set network card name enp0s37f2: dhcp4: no dhcp6: no # set your static ip # default network mask length is 24 # 255.255.255.0 -->24 addresses: [192.168.10.56/24] # set ipv4 gateway address gateway4: 192.168.10.254 nameservers: # set dns servers addresses: [114.114.114.114,8.8.8.8] version: 2应用修改# 生成配置文件 sudo netplan --debug generate # 测试配置文件 sudo netplan try # 应用修改 sudo netplan apply # 重启网络服务 sudo systemctl restart network-manager17. 创建随机文件
在Linux系统中有/dev/random和/dev/urandom可以产生随机数,前者是更加贴近数学意义的随机数,后者是比较适合生成文件的随机数,用法如下: # 执行命令:创建65536*1024Bytes(64MB)的文件 dd if=/dev/urandom of=test.txt count=65536 bs=1024 # 命令输出 # 65536+0 records in # 65536+0 records out # 67108864 bytes (67 MB, 64 MiB) copied, 10.4984 s, 6.4 MB/s还可以创建全是0的文件: # 执行命令:创建65536*1024Bytes(64MB)的文件 dd if=/dev/zero of=test-0.txt count=65536 bs=1024 # 命令输出 # 65536+0 records in # 65536+0 records out # 67108864 bytes (67 MB, 64 MiB) copied, 9.42672 s, 7.1 MB/s另外,可以尝试使用zip或rar算法单独压缩这两个文件,会发现后者可以被压缩到1MB以下,而前者基本不会减小体积(信息熵的体现)18. 重定向输出与2>&1介绍
在linux终端下,可以在shell命令的后面,使用符号>和>>来进行标准输出的重定向(不包括执行出错的信息,即标准错误) >a.txt表示将终端要显示的信息全部写入文件(若文件已存在,则覆盖)>>a.txt表示将终端要显示的信息全部写入文件(若文件已存在,则追加)例如: zfb@myServer:~$ echo "hello, world" hello, world zfb@myServer:~$ echo "hello, world" >a.txt zfb@myServer:~$ cat a.txt hello, world zfb@myServer:~$ echo "this is second command" >a.txt zfb@myServer:~$ cat a.txt this is second command zfb@myServer:~$ echo "The 3rd command" >>a.txt zfb@myServer:~$ cat a.txt this is second command The 3rd command zfb@myServer:~$关于2>&1的解释,每个程序或命令在运行后,都会至少打开三个文件描述符以存放命令的各种输入输出信息: 标准输入:对应文件/dev/stdin,也可以使用文件描述符0表示标准输出:对应文件/dev/stdout,也可以使用文件描述符1表示标准错误:对应文件/dev/stderr,也可以使用文件描述符2表示于是,很容易理解:2>&1表示将文件描述符2(标准错误)的内容重定向到文件描述符1(标准输出)当没有&时,1会被认为是一个普通的文件,&表示重定向的目标不是一个文件,而是一个文件描述符 通过命令./test.sh 2>&1 >a.txt即可实现脚本执行过程的标准输出和标准错误都写入文件a.txt 参考如下信息 zfb@myServer:~$ ls -al /dev/std* lrwxrwxrwx 1 root root 15 Dec 23 13:36 /dev/stderr ->/proc/self/fd/2 lrwxrwxrwx 1 root root 15 Dec 23 13:36 /dev/stdin ->/proc/self/fd/0 lrwxrwxrwx 1 root root 15 Dec 23 13:36 /dev/stdout ->/proc/self/fd/1 zfb@myServer:~$19. 记录终端信息
使用script命令开启记录:script -t 2>time.file -a -f command.log -t表示输出时间信息到标准错误(文件描述符2)2>time.file表示将标准错误信息输出到文件(time.file是自己设置的文件名称)-a表示追加模式-f表示每次写入后都刷新缓存-q表示安静运行模式(不会提示Script started以及Script done)command.log是自己设置的用来保存输入命令和终端回显信息的文件名称最简单的用法为script,该命令会自动将输入命令和终端回显信息写入当前目录的typescript文件 其次还可以使用script command.log,该命令会自动将输入命令和终端回显信息写入当前目录的command.log文件退出记录:在终端使用命令exit或者快捷键Ctrl + D 使用示例: zfb@myServer:~$ script -t 2>time.file -a -f command.log Script started, file is command.log zfb@myServer:~$ echo "hello, world" hello, world zfb@myServer:~$ echo $(date "+%Y-%m-%d %H:%M:%S") 2020-12-23 20:48:46 zfb@myServer:~$ echo "Bye" Bye zfb@myServer:~$ ls -al total 20 drwxr-xr-x 2 zfb zfb 4096 Dec 23 20:48 . drwxr-xr-x 37 zfb zfb 4096 Dec 23 20:49 .. -rw-r--r-- 1 zfb zfb 0 Dec 23 19:03 a.txt -rw-r--r-- 1 zfb zfb 12 Dec 23 19:04 b.txt -rw-r--r-- 1 zfb zfb 2744 Dec 23 20:49 command.log -rw-r--r-- 1 zfb zfb 790 Dec 23 20:49 time.file zfb@myServer:~$ exit Script done, file is command.log zfb@myServer:~$查看保存的命令和终端回显:cat command.log 该命令得到输出如下 zfb@myServer:~$ cat command.log Script started on 2020-12-23 20:48:25+08:00 [TERM="xterm-256color" TTY="/dev/pts/0" COLUMNS="75" LINES="30"] zfb@myServer:~$ echo "hello, world" hello, world zfb@myServer:~$ echo $(date "+%Y-%m-%d %H:%M:%S") 2020-12-23 20:48:46 zfb@myServer:~$ echo "Bye" Bye zfb@myServer:~$ ls -al total 20 drwxr-xr-x 2 zfb zfb 4096 Dec 23 20:48 . drwxr-xr-x 37 zfb zfb 4096 Dec 23 20:49 .. -rw-r--r-- 1 zfb zfb 0 Dec 23 19:03 a.txt -rw-r--r-- 1 zfb zfb 12 Dec 23 19:04 b.txt -rw-r--r-- 1 zfb zfb 2744 Dec 23 20:49 command.log -rw-r--r-- 1 zfb zfb 790 Dec 23 20:49 time.file zfb@myServer:~$ exit Script done on 2020-12-23 20:49:04+08:00 [COMMAND_EXIT_CODE="0"] zfb@myServer:~$注意: 在上面显示的内容中,只有命令cat command.log是手动输入的,其他都是自动显示的根据上面显示的时间2020-12-23 20:48:46,可以看出并不是重新执行了一遍,而是重新显示了一遍另外,还可以使用命令scriptreplay来重新播放命令与回显(只是把当时记录的信息,播放一遍,不是重新执行) 命令为:scriptreplay -d 1 -m 2 -t time.file -s command.log -d表示倍速播放:-d 2表示播放速度是原始输入单条命令的速度的两倍;-d 0.1表示播放单条命令的速度减慢10倍-m表示命令之间的最大延迟时间(单位是秒):-m 2表示command.log中存放的两条命令之间的间隔时间如果大于两秒,则按两秒执行播放-t表示后面指定存放时间信息的文件-s表示后面指定存放输入和回显信息的文件示例如下: zfb@myServer:~$ scriptreplay -d 1 -m 2 -t time.file -s command.log zfb@myServer:~$ echo "hello, world" hello, world zfb@myServer:~$ echo $(date "+%Y-%m-%d %H:%M:%S") 2020-12-23 20:48:46 zfb@myServer:~$ echo "Bye" Bye zfb@myServer:~$ ls -al total 20 drwxr-xr-x 2 zfb zfb 4096 Dec 23 20:48 . drwxr-xr-x 37 zfb zfb 4096 Dec 23 20:49 .. -rw-r--r-- 1 zfb zfb 0 Dec 23 19:03 a.txt -rw-r--r-- 1 zfb zfb 12 Dec 23 19:04 b.txt -rw-r--r-- 1 zfb zfb 2744 Dec 23 20:49 command.log -rw-r--r-- 1 zfb zfb 790 Dec 23 20:49 time.file zfb@myServer:~$ exit zfb@myServer:~$注意: 在上面显示的内容中,只有命令scriptreplay -d 1 -m 2 -t time.file -s command.log是手动输入的,其他都是自动显示的根据上面显示的时间2020-12-23 20:48:46,可以看出并不是重新执行了一遍,而是重新播放了一遍与cat command.log的不同之处在于,显示效果与手动输入一致,适合作为教程演示可以把time.file和command.log文件移动到任意一台支持scriptreplay命令的机器上,都可以重现命令输入与终端回显20. 记录服务器用户会话操作
使用root用户登录服务器,创建文件夹: sudo mkdir -p /var/log/script-records/ sudo chmod 733 /var/log/script-records/然后编辑文件/etc/profile:sudo vim /etc/profile 在文件末尾追加以下内容: if [ $UID -ge 0 ] then exec /usr/bin/script -t 2>/var/log/script-records/$USER-$UID-`date +%Y%m%d`.time -a -f -q /var/log/script-records/$USER-$UID-`date +%Y%m%d`.log【Ubuntu系统基础命令解析:SSH保活、用户管理、开机自启与后台任务运行技巧】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
终于懂了为什么这么多人推荐Ubuntu,这些基础命令太实用了!
有9位网友表示赞同!
之前一直不知道怎么用ssh保活,这篇文章简直敲击我的灵魂啊!
有8位网友表示赞同!
用户管理也太重要了吧,以后想自己创建一个专属账户就轻松多了。
有17位网友表示赞同!
开机自启功能真是神级设计,可以让我不用每次都手动运行软件了。
有11位网友表示赞同!
后台运行功能能让我同时处理好多事,效率大大提升!
有19位网友表示赞同!
这篇文章涵盖了我最近想要学习的Ubuntu知识点,太棒啦!
有20位网友表示赞同!
以前在其他系统上使用这些命令都很麻烦,Ubuntu操作真方便!
有20位网友表示赞同!
感谢作者分享这些实用的Ubuntu命令,让我能更好地利用它!
有5位网友表示赞同!
学习这些基础命令能让我的Linux使用体验更棒!
有10位网友表示赞同!
这篇文章对小白很有帮助,我终于敢尝试更强大Linux系统了。
有9位网友表示赞同!
以后再也不用害怕忘记运行某些软件了,开机自启真是太贴心!
有11位网友表示赞同!
后台运行功能让我可以一边玩游戏一边还能处理文件,真不错!
有13位网友表示赞同!
学习Ubuntu的这些技巧,感觉自己一下子变身高手了!
有15位网友表示赞同!
这篇文章内容很详细,讲解也很清晰易懂!
有10位网友表示赞同!
终于知道怎么利用ssh保活,节省时间又安全!
有16位网友表示赞同!
以后就可以自己管理自己的Ubuntu环境啦!
有19位网友表示赞同!
这些命令可以帮助我整理我的工作流程,提高效率!
有14位网友表示赞同!
希望以后还能看到更多关于Ubuntu的实用指南!
有12位网友表示赞同!
学习linux真是太有意义了,掌握这些技能能让我在未来的职业生涯中更有竞争力!
有14位网友表示赞同!