进行Fedora的安装并对系统进行初步配置

Fedora的安装

Fedora是RedHat公司支持的社区发行版,当前最新为Fedora26,我们使用其workstation版本(适用于PC和笔记本)。

  1. 虚拟机安装
  2. 安装在虚拟机(VirtualBox下载)中只是一个体验或临时方案,因速度问题,不推荐,但由于U盘安装不成功或可能导致数据丢失,也建议初学者使用。

  3. U盘安装(双系统)
  4. 使用Linux,最好是独立的安装该系统,能获得最佳体验。

    先获取Fedora的ISO文件(请前往LUNA校内镜像站下载)和U盘引导制作工具Rufus

    准备一个4G+的U盘,运行Rufus,按提示操作即可将FedoraISO写入U盘(注意,请将U盘中的EFI文件夹删除,以让老旧的计算机也可顺利安装!!!)。

    在你的PC或笔记本上预留50G+的空间(请一定记住空间大小,避免出错),使用磁盘管理工具将其删除,成为未分配空间。然后准备安装Fedora。

    重启计算机,选择U盘启动即可。

    建议:初学者请让系统自动分区;语言支持请选择英文和中文环境,默认英文;新建的用户勾选添加到管理组;

  5. 使用已安装好的CentOS
  6. 如果上面的方式没有成功,你可以远程使用我们已经安装好的CentOS系统(10.1.74.120)。

    下载SSH客户端MobaXterm。运行后SSH连接服务器10.1.74.120(一般用户st:ts,根用户root:toor),然后你可做任何事情!

Fedora的初步配置

如果因某种原因网络没能正常工作,可使用图形界面或命令行方式进行配置。以下为命令行配置方式:


ifconfig    #查看网卡名称如 enpXXX等(如果是无线,则配置文件为ifcfg-AP名称),下面的命令要使用
sudo vim /etc/sysconfig/network-scripts/ifcfg-enpXXX     #修改内容,注意ONBOOT需设置为yes
sudo service network restart    #重启网络

配置优质的软件源不仅能及时获得上游更新,还能拥有各种各样的软件支持。作为天朝子民,访问外网速度过慢。因此在开始安装工作前,配置国内源几乎是首选的行动。


#dnf是Fedora新的软件包管理工具,如没有则使用sudo yum install dnf进行安装
# RPM Fusion Free 源
sudo dnf install http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-26.noarch.rpm -y
# RPM Fusion Nonfree 源
sudo dnf install http://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-26.noarch.rpm -y
#启用 FZUG 源
sudo dnf config-manager --add-repo=http://repo.fdzh.org/FZUG/FZUG.repo
#启用阿里源
sudo dnf config-manager --add-repo=http://mirrors.aliyun.com/repo/fedora.repo
#更新缓存(添加源后需要进行缓存更新)
sudo dnf makecache
#执行更新
sudo dnf update

下载微软雅黑微软雅黑粗体苹果摩纳哥字体,双击即可安装。然后使用以下命令安装的tweak-tool工具进行字体配置,前面三个使用yahei,终端(等宽字体)使用monaco。(还可以进行主题、开机启动、背景等设置)


sudo dnf install gnome-tweak-tool

安装系统时选择了两种语言支持,所以输入法直接在系统设置->地区和语言->输入法添加中文输入即可。默认使用shift进行切换,还可设置拼音更正、模糊音等设置。


sudo dnf install p7zip p7zip-plugins
#使用 “a” 选项就可以创建(添加)一个归档文件,它可以创建 7z、XZ、GZIP、TAR、 ZIP 和 BZIP2 这几种格式的文件。如果指定的归档文件已经存在的话,它会把文件“附加”到存在的归档中,而不是覆盖原有归档文件。
7z a <archive-filename> <list-of-files> 
#使用 “x” 选项可以全路径抽取一个归档文件,抽取出的文件会放在当前目录。抽取支持的格式比创建时支持的格式要多的多,包括 7z、XZ、GZIP、TAR、ZIP、BZIP2、LZMA2、CAB、ARJ、CPIO、RPM、ISO 和 DEB 这些格式。
7z x <archive-filename>
7z l  <archive-filename>	#查看压缩文件


#install the key and repository
sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
sudo sh -c 'echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com/yumrepos/vscode\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" > /etc/yum.repos.d/vscode.repo'

#Then update the package cache and install the package using dnf (Fedora 22 and above):

sudo dnf check-update
sudo dnf install code

终端执行code或配置年快捷方式ctrl+alt+C即可
插件见code,安装yahei, source code pro, monaco等字体后配置如下:
File->Preferences->Settings->editor font-family, 点击编辑,写入以上字体即可.注意,权限问题,配置只能写到用户setting中。

卸载Libre Office,安装WPS。WPS Office比Libre更好的兼容MS Office系列。内网下载WPS安装包


sudo dnf remove libreoffice*
sudo dnf install wps-office.rpm 或直接双击安装
#注意:安装完成后如幻灯片不能运行,执行sudo ln -s /lib64/libbz2.so.1 /lib64/libbz2.so.1.0可解决

说起英文都是泪,安装一个翻译工具吧。下载 StarDict桌面翻译工具朗道英汉词典、 朗道汉英词典


#双击安装下载的rpm包即可
tar -xjvf stardict-langdao-ec-gb-2.tar.bz2 -C /usr/share/stardict/dic   #安装朗道英汉词典                        
tar -xjvf stardict-langdao-ce-gb-2.tar.bz2 -C /usr/share/stardict/dic   #安装朗道汉英词典

终端是我们需要的重要工具,Fedora自带的终端已经比较好了,但你也可以安装一个下拉式终端Guake。安装完毕后可以进行字体、透明度、热键等配置。


sudo dnf install guake

强大的分屏工具,提高效率,且session不会关闭。


sudo dnf install tmux   #安装tmux
vim ~/.tmux.conf        #添加如下配置信息
unbind C-b
set -g perfix C-a
set -g default-terminal "screen-256color"
unbind %
bind \ split-window -h
unbind '"'
bind - split-window -v
#配置完毕后,tmux运行即可,所有操作皆以Ctrl+a开始。以下为其常用方式
\       #垂直分隔
-       #水平分隔
x       #删除面板
z       #最大化面板
d       #暂时退出tmux
tmux attach     #返回tmux

系统中有经常需要使用的程序,我们可以设计键盘快捷方式来快速启动。在系统->设置->键盘中设置即可,如定义Ctrl+Alt+T就可以启动Guake Terminal

Shell命令是使用Linux的强大、灵活以及轻量的工具。本部分实验要求对常用Shell命令进行熟练应用,在终端中完成。

格式

命令名称 [命令参数] [命令对象]

命令名称只能是小写的英文单词或缩写,如date、cp(copy)等。

[ ]表明这部分可选。命令对象即操作的对象如文件、目录、用户等,而参数则提供许多的选项(单字母用- 单词用--),初学者可记住一些常见的参数即可。

命令成功执行返回0,否则为其它值,可用echo $?查看。

man-帮助手册

任何命令都有manual,使用man 命令名称即可得到帮助。

常用系统工作命令

echo-回显


echo fedoraproject.org  #显示字符串
echo $SHELL             #显示系统变量
echo $HOSTNAME          #显示系统变量
echo $PATH              #显示系统变量

date-显示/设置系统日期时间


date                        #显示系统日期时间
date -s "19890604 1:00:00"  #设置系统日期时间
date "+%j"                  #今天为本年第几天

其它简单命令


cal         #显示本月日历(cal 06 1989)
who         #当前登录用户信息
w           #当前用户在做what     
last        #最近登录用户信息
clear       #清屏
passwd      #修改当前用户口令
ifconfig    #查看当前网卡状态
uname -a    #查看内核版本、处理器类型等
uptime      #查看系统上线时间/用户/负载(最近1、5、15分钟的平均负载)
free -h     #查看内存使用
du -hs /home    #查看某目录空间使用情况(disk used)
df -h       #查看整个磁盘文件系统使用/映射情况(disk filesystem)
top         #系统整体信息
history     #查看历史命令(位于~/.bash_history文件,默认1000条,可修改/etc/profile文件中的HISTSIZE的值)
sudo reboot/poweroff    #重启/关机

下载及网站镜像命令


wget http://10.1.74.132/操作系统/Linux/Fedora/Fedora-Workstation-Live-x86_64-26-1.5.iso         #下载文件
wget -rpb https://mdbootstrap.com         #递归全站下载,后台运行
httrack https://mdbootstrap.com &         #全站镜像,后台运行(比wget更好用,如果没有请使用dnf安装)

目录及文件相关命令

请查看教材P.51(2.5.1)、P.39(2.3)讲述的目录及文件相关概念。


pwd         #Print Work Directory,显示当前目录,可用tree显示目录树
cd          #Change Directory,注意.、..、~
ls -alh /   #List,all/list/human,注意?和*
cat -n /etc/passwd         #catenate(字符串连接),带行号显示文本文件
tac/more/less/head/tail    #tac逆序;more和less分屏显示,其中less可前后翻;head和tail查看前/后10行
wc /etc/passwd             #Word Count,统计行、字和字节数
touch newFile.txt          #修改文件时间或新建空文件
grep "wang" /etc/passwd    #在文件中查找带指定字符串的行
mkdir -p test1/test2/test3     #parents,p参数可创建新的3个目录
cp 源文件/目录 目的文件/目录     #copy,可带路径;参数r可用于递归复制目录
mv 源文件/目录 目的文件/目录     #move,移动/改名
rm 文件/目录                         #remove,删除文件/目录,-rf将强制递归删除目录(慎用!)
tar -czvf doc.tar.gz ./Docment      #压缩Docment目录(gz格式),可用空格分隔多个文件和目录,create/compress/verbose/file
tar -cjvf doc.tar.bz2 ./Docment     #压缩Docment目录(bzip2格式)
tar -xzvf doc.tar.tar.gz -C ./test  #解压到指定目录,否则当前目录
tar -xjvf doc.tar.bz2            #解压到当前目录
tar -tvf doc.tar.gz              #查看压缩文件
which ls            #在PATH变量中查找可执行文件位置,通常测试是否有该命令
locate passwd       #在文件系统查找与passwd相关的文件
ln -s test.txt sl-test  #新建软链接,类似于快捷方式,但sl-test是个独立的文件(有不同的INode),删除原文件该链接文件仍存在,但链接失效(重建同名文件生效)
ln test.txt l-test      #新建硬链接,与原文件有相同的INode,增加链接数(如变为2),删除该硬链接或原文件数据都在,除非链接数为0

文件用户与文件权限

为安全考虑,Linux设定了三种类型的用户(/etc/passwd文件中。/etc/shadow文件是其对应的密码):

  1. 超级用户root(UID:0),系统整个系统的管理员
  2. 系统用户(UID:1~999),运行系统服务所需要的用户角色(如nginx用户等)
  3. 普通用户(UID:1000~)

针对文件,Linux也设定了三种用户身份:文件主(uer)、同组用户(group)和其它用户(others)。无需说明,超级用户(root)具有所有权限!。

三种用户身份对文件都有3种操作权限:读r(read,100-4)、写w(write,010-2)、执行x(execute,001-1)。请使用ls -l查看。

注意:每行第一个字符列出了类型,常见的是:- 文件;d 目录;l 链接。接下来的9个字符表明的owner、group和others的rwx权限。

新建文件默认用户和同组用户具有rw,其它用户具有r权限。我们可以使用chmod命令对u/g/o/a的rwx权限进行+/-/=设定。


chmod a+x test.txt              #all,所有用户添加执行权限
chmod u-x,g-wx,o-x test.txt     #取消用户的执行权限、同组用户的写和执行权限、其它用户的执行权限
chmod u=rwx,g=rw,o=r test.txt   #字符绝对方式设置
chmod 760 test.txt              #数字绝对方式设置

系统配置、程序编写都需要文本编辑器。你可选用GUI方式的编辑器如gedit、vscode等,但远程进行配置时,字符模式下的文本编辑器就是必须掌握的!而vim就是其中的神器。

启动

vim hello.c      #有该文件则打开,否则新建

模式

vim有两种工作模式:命令模式和插入模式。

进入vim时默认进入命令模式,可进行剪切、复制、粘贴、保存、退出等操作;

i(表示insert)或a(表示append)等进入插入模式,可以输入文字。

输入完成,敲esc键回到命令模式。

命令模式下常用命令

  • 光标移动:方向键,PageDown,PageUp,gg-首行,G-末行
  • 文本选择:v键,然后移动光标
  • 文本剪切:选择后,使用x或del键,同时删除的内容进入剪贴板
  • 文本复制:选择后,使用y键,内容进入剪贴板
  • 文本粘贴:p键,将当前剪贴板内容插入到光标位置
  • 删除整行:dd,如果先输入数字再敲dd则删除指定行数
  • 查找:/+查找内容,n或N前进后退,高亮显示将一直存在,使用:nohl取消
  • 替换::%s/old/new/g,将old全部替换为new。g-global,如果加上c参数,则表示需要确认confirm
  • 撤销/重做:u/Ctrl+r,u-undo,Ctrl+r-redo
  • 临时退出:当需要临时退出vim回到shell时,:sh即可,exit返回vim编辑器
  • 保存/退出::w-保存,:x-保存退出,:q!-强制退出(不保存)
  • 显示行号::set nu

vim还有许多插件可用,请根据自己的需求随时Google

利用强大的Shell进行脚本(Script)编程,进行批处理操作。

实验二中,我们在Shell使用了许多命令进行操作,输入一条命令,Shell进行解释并执行,这称为交互式(Interactive)。

我们也可以先编写一个Shell脚本(Script),使用结构化(选择、循环等)设计来包含诸多的命令,让Shell一次性执行,这称为批处理(Batch)

Shell Script基础


date ; who      # 命令行中多个命令使用;进行分隔即是Shell Script!

使用任何文本编辑器,将多个Shell命令写在一个文本文件(一般后缀为.sh)中即为脚本文件。我们可使用vim编辑如下脚本并保存为first.sh文件。

任何脚本文件第一行都需写上#!后面跟上Shell解释器的路径。以下代码表明使用bash进行解释执行(当然也可使用其它shell解释器)


#!/bin/bash 
#这是注释行  
date
who

运行first.sh,你将会得到command not found的提示。因为Linux将把它当作命令执行,将会在系统路径中查找(echo $PATH),然后,没找到 :(

思考:那么把该文件放到PATH中又如何?

如果我们指定路径./first.sh或把该脚本文件放到系统路径中,你又会得到Permission denied!表明没有权限!

使用ls -l查看该文件的权限,你发现了什么?该文件需要执行权限,使用chmod u+x first.sh设置。

OK,大功告成!

提示:你也可以什么都不设置,直接使用sh test.sh进行运行。


#!/bin/bash
echo 这是一个显示测试,ha ha ha!     #也可将信息用双/单引号包裹
echo Let's see if this'll work.     #注意结果,考虑使用转义字符\
echo -n 现在是:                      #参数n表明不换行
date
echo 当前用户信息:
echo USER: $USER    UID: $UID  HOME: $HOME

思考:echo The cost of the item is $15.结果?

除了系统变量外,Shell支持脚本中用户自定义变量用于各种目的。

用户变量限定20个字符(字母、数字、下划线),大小写敏感!


#!/bin/bash
days=10
guest="Elon Musk"
cost1=99
echo "$guest checked in $days days ago, the cost is \$$cost1."
days=5
guest="Tesla"
cost2=$cost1    #注意cost1前的$表明获取变量cost1的值
echo "$guest checked in $days days ago, the cost is \$$cost2"

思考:以上代码中,如果改为cost2=cost1会发生什么?

我们如果在脚本中需要获取某命令的输出结果,则使用命令替换。其格式是将命令放在$()``中(注意是反单引号!)。


#!/bin/bash
now=`date`
echo "The date and time are: " $now
today=$(date +%Y%m%d)
touch mylog-$today.log
ll

我们执行命令,结果将输出到屏幕(控制台)。但如果我们需要输出到其它地方如保存到一个文件中,则需要使用重定向。其格式是command > outputfile


#!/bin/bash
ls xxx.txt          #当前没有该文件
date > xxx.txt      #屏幕将没有输出,结果被重定向到xxx.txt文件中
ls xxx.txt
cat xxx.txt
who >> xxx.txt
echo ====新的内容被添加了====
cat xxx.txt
echo ====下面是输入重定向====
wc < xxx.txt

有时,一个命令的输出需要作为另一个命令的输入,我们当然可以使用上面的重定向,但这样很累赘。我们应该使用管道,其格式是command1 | command2


#!/bin/bash
ls /usr/bin | more
ls /usr/bin | grep zip | wc > zip.count
cat zip.count

任何一门编程语言进行运算都是小case,不幸的是在shell中有点尴尬。我们得使用这样的格式$[ operation ] (特别要注意,运算式的两端必须有一个空格!当然使用后叙的双括号表达式可以简化)


#!/bin/bash
result=6+4
echo $result        #注意结果
result=$[ 6+4 ]
echo $result
a=89
b=64
c=$[ $a/$b ]
echo $c             #注意结果

浮点运算:在shell中进行浮点运算就更不友好了,因为shell脚本毕竟不像C语言之类不是用来进行科学计算而多用于系统管理的。请有需要时查阅相关文档。

结构化命令

使用if-then-fi,各关键词单独一行,如果希望把then写到和if同行,则需用;分隔。


#!/bin/bash
if pwd      #该命令成功执行则为TRUE,否则FALSE
then
  echo "It worked"
fi
echo =====这是分割线=====
if IamNotaCommand
then
  echo "It worked"
fi
echo "We are outside the if statement"
echo =====这是分割线=====
testuser=wang
if grep $testuser /etc/passwd
then
  echo "This is my first command"
  echo "This is my second command"
  echo "I can even put in other commands besides echo:"
  ls -a /home/$testuser/.b*
fi

使用if-then-else-fi,各关键词单独一行,如果希望把then写到和if同行,则需用;分隔。


#!/bin/bash
testuser=NoSuchUser
if grep $testuser /etc/passwd
then
  echo "The bash files for user $testuser are:"
  ls -a /home/$testuser/.b*
  echo
else
  echo "The user $testuser does not exist on this system."
  echo
fi

使用if-then-elif-then-...-else-fi,各关键词单独一行,如果希望把then写到上一行,则需用;分隔。


#!/bin/bash
testuser=NoSuchUser
if grep $testuser /etc/passwd       #是否有该用户
then
  echo "The user $testuser exists on this system."
elif ls -d /home/$testuser          #没有该用户,是否有其home目录
then
  echo "The user $testuser does not exist on this system."
  echo "However, $testuser has a directory."
else                                #两者都没有
  echo "The user $testuser does not exist on this system."
  echo "And, $testuser does not have a directory."
fi

嵌套的if:显然,如果需要,在以上结构中可以进行嵌套。

test: 如果你细心点,会发现我们测试的条件都是某个命令是否成功执行,且结果还会输出,在命令请加上test就干净多了。

使用case可以简化某些代码,请看如下例子


#!/bin/bash
read -p "Please input your score: " score   #从控制台读取数据到变量score中
grade=$[ $score/10 ]
case $grade in
9 | 10)                     #注意后小括号
  echo "hahaha"
  echo "Yes, Great!";;    #注意分号
8)
  echo "Good!";;
7)
  echo "OK!";;
6)
  echo "Pass!";;
5 | 4 | 3 | 2 | 1 | 0)
  echo "Bad!";;
*)
  echo "Wrong score!";;
esac

使用-eq、-ge、-gt、-le、-lt、-ne进行数字比较。


#!/bin/bash
value1=10
value2=11
if [ $value1 -gt 5 ]        #注意该数字比较的写法
then
  echo "The test value $value1 is greater than 5"
fi
#
if [ $value1 -eq $value2 ]
then
  echo "The values are equal"
else
  echo "The values are different"
fi

浮点数比较:注意,在shell中不能进行浮点数的比较。

使用=、!=、<、>、-n、-z进行字符串比较。其中-n、-z表示字符串长度是否不为0或等于0

另外, < 和 > 必须要添加 \ 进行转义,因为shell把他们看着重定向的符号!


#!/bin/bash
val1=baseball
val2=hockey
if [ $val1 \> $val2 ]       #注意转义
then
  echo "$val1 is greater than $val2"
else
  echo "$val1 is less than $val2"
fi
echo ====这是分割线====
val1=testing
val2=''
if [ -n $val1 ]
then
  echo "The string '$val1' is not empty"
else
  echo "The string '$val1' is empty"
fi
if [ -z $val2 ]
then
  echo "The string '$val2' is empty"
else
  echo "The string '$val2' is not empty"
fi

使用-d、-f、-e等进行文件测试。分别表示存在且是目录、存在且是文件、存在。其它参数如可否执行、写入等请查阅资料。


#!/bin/bash
tempDir=/home/wang/xxx
if [ -d $tempDir ]
then
  echo "The $tempDir directory exists"
  cd $tempDir
  pwd
else
  echo "The $tempDir directory does not exist, let's make it!"
  mkdir $tempDir
  cd $tempDir
  pwd
fi

#!bin/bash
location=$HOME
file_name="test.log"
if [ -e $location ]
then #Directory does exist
  echo "OK on the $location directory."
  echo "Now checking on the file, $file_name."

  if [ -e $location/$file_name ]
  then #File does exist
    echo "OK on the filename"
    echo "Updating Current Date..."
    date >> $location/$file_name
  else #File does not exist
    echo "File does not exist, let's build it and update."
    date > $location/$file_name
  fi
else    #Directory does not exist
  echo "The $location directory does not exist."
  echo "Nothing to update"
fi

使用&&、||、!进行逻辑测试。


#!/bin/bash
if ! [ -d $HOME/yyy ]
then
  echo "Make yyy Directory"
  mkdir $HOME/yyy
fi
if [ -d $HOME ] && [ -w $HOME/testing ]     #-w表示有testing文件且有写权限
then
  echo "The file exists and you can write to it"
else
  echo "I cannot write to the file"
fi

对于各种数学、关系以及逻辑等表达式,我们也可以使用((expression))的形式进行运算,这样比较接近数学表达。但仍注意只针对整数。


#!/bin/bash
val1=10
if (( val1 ** 2 > 90 ))     #注意:双圆括号中的变量可以不用$
then
  (( val1++ ))
  (( val2 = val1 ** 2 ))
  echo "The square of $val1 is $val2"
fi

使用传统的for循环,在shell中可以使用for (( variable assignment ; condition ; iteration process ))的形式,如下所示:


#!/bin/bash
for (( i = 1; i <=10; i++ ))
do
  echo "The next number is $i"
done
#--------Fibonacci Sequence---------
f1=1
f2=1
echo -n "The Fibonacci Sequence is: $f1 $f2"
for (( i = 3; i <=20; i++ ))
do
  ((f3=f1+f2))
  echo -n " $f3"
  ((f1=f2))
  ((f2=f3))
done

shell可以让我们对一组值(目录、文件以及文件的行等)进行重复操作及迭代或遍历,在shell中可以使用for var in list的形式,如下所示:


#!/bin/bash
for state in Alabama Alaska Arizona Arkansas California Colorado
do
  echo The next state is $state
done
#---遍历命令输出---
file="states"
content=$(cat $file)    #注意:文件中的内容默认以空格、tab和回车为分隔符
for state in $content
do
echo "Visit beautiful $state"
done
#---以文件通配符遍历---
for file in /home/wang/test/*
do
  if [ -d "$file" ]
  then
    echo "$file is a directory"
  elif [ -f "$file" ]
  then
    echo "$file is a file"
  fi
done        #注意:done后如果加上 > out.txt 则输出循环结果到文件

这两种循环例子如下:


#!/bin/bash
#----while,条件为TRUE执行----
var1=10
while [ $var1 -gt 0 ]   #改为((var1>0))也可
do
  echo $var1
  var1=$[ $var1 - 1 ]   #改为((var1--))也可
done
#----until,条件为FALSE执行----
var1=100
until [ $var1 -eq 0 ]   #改为((var1==0))也可
do
  echo $var1
  var1=$[ $var1 - 25 ]  #改为((var1-=25))也可
done

嵌套循环:显然,如果需要,在以上结构中可以进行循环嵌套。

控制循环:使用break [n] 以及 continue [n]也可以对循环进行控制,其中可选的n表示终止循环的层数/次数。

练习一:列出系统路径目录中的可执行文件

#!/bin/bash
IFS_OLD=$IFS
IFS=:               #设置新的文件内容分隔符
for folder in $PATH
do
  echo "$folder:"
  for file in $folder/*
  do
    if [ -x $file ]
    then
      echo " $file"
    fi
  done
done
IFS=$IFS_OLD        #还原分隔符为默认
练习二:打印用户指定行数的*,第一行1个,第二行2个,依次类推

#!/bin/bash
read -p "Please input number of lines: " line
for (( i=1; i<=line; i++))
do
  for (( j=1;j<=i; j++))
  do
    echo -n "*"
  done
  echo
done

处理输入

脚本运行时,我们可以给程序传入需要的数据,这一般分为命令行参数以及运行时输入两种情况。

假设我们的脚本将对两个给定的数进行求和,并使用命令行参数形式即:./add.sh 89 64(注意以空格分隔),则在脚本中我们可以通过$0、$1、$2得到对应的三个值并进行使用,如参数更多则依此类推。代码如下:


#!/bin/bash
#----求和----
if(($# == 2))   #参数个数,也可写为 if [ $# eq 2 ]
then
  echo "The script's name is $0"
  ((sum=$1+$2))
  echo "$1 + $2 = $sum"
else
  echo "The script need two parameters!"
fi
#----阶乘----
if(($# == 1))
then
  factorial=1
  for (( number = 1; number <= $1 ; number++ ))
  do
    ((factorial *= $number))
  done
  echo The factorial of $1 is $factorial
else
  echo The script need a parameter!

在脚本运行过程中要求用户提供数据,我们使用read


#!/bin/bash
echo -n "Enter your name: "     #不换行
read name
echo "Hello $name, welcome to my program. "
#----带提示---------
read -p "Please enter your age: " age 
days=$[ $age * 365 ]    #((days=age*365))
echo "That makes you over $days days old! "
#-----n1表示接受到一个字符后无需回车,自动往下执行----
read -n1 -p "Do you want to continue [Y/N]? " answer    
case $answer in
  Y | y)
    echo
    echo "fine, continue on…";;
  N | n)
    echo
    echo OK, goodbye
    exit;;      #直接退出脚本执行
esac
echo "This is the end of the script"
#----silence----
read -s -p "Enter your password: " pass
echo
echo "Is your password really $pass? "
#----从文件中接收数据,方法一----
#The quick brown dog jumps over the lazy fox.
#This is a test, this is only a test.
#O Romeo, Romeo! Wherefore art thou Romeo?
count=1
cat data.txt | while read line
do
  echo "Line $count: $line"
  ((count++))
done
echo "Finished processing the file"
#----从文件中接收数据,方法二----
while read line
do
  echo $line
done < data.txt
#----从文件中接收数据,方法三----
#注意:while以换行为分隔,for还会以空格为分隔
for line in `cat data.txt`      
do
  echo $line
done

script控制

脚本运行时,我们有许多的选项来控制脚本的运行。

脚本运行过程中,Ctrl+c将终止运行(SIGINT信号),Ctrl+z将暂停执行(SIGTSTP信号)。


sleep 1000       #ctrl+c,可看到被终止
sleep 1000       #ctrl+z,可看到暂停的信息,如进程job number为1
sleep 1000       #ctrl+z,可看到暂停的信息,如进程job number为2
ps -l           #查看当前进程状态,S列中的T表明为STOP状态
kill -9 PID     #-9表示无条件终止进程
bg/fg           #在后台/前台恢复被暂停的执行,可加上job number指定

我们也可以在脚本中用trap对这些信号进行捕获,来决定如何处理


#!/bin/bash
trap "echo 'You can not interrupt me!'" SIGINT
count=1
while((count<=10))
do
  echo "loop #$count"
  sleep 1
  ((count++))
done

如果一个脚本运行时间长,则在前台运行就不合适,此时运行脚本的命令加上 & 即表示要在后台运行,如:./test.sh &

这样输出将会前台显示,我们可以用重定向解决。但还有一个问题是shell关闭后,运行的脚本进程也被杀死。对于这种需要长时间运行的情况,我们使用nohup ./test.sh &来执行。

执行这种任务的另一个好方法是tmux

当需要定时执行任务时如:整理文件、午夜杀毒、文件备份或重新启动Web服务器等等,我们可以使用at -f test.sh 时间命令让脚本在指定的时间运行。时间格式有10:10、10:10PM、now、noon、midnight、10:10 + 7 days等

atq可列出计划任务,atrm 任务号可取消

函数

函数可以让我们结构清晰、代码重用等,在各种语言中得到广泛的使用。


#!/bin/bash
#函数必须先定义再使用
function doubleYou {    #函数名后可选(),如果有(),function关键字可省略
  read -p "Enter a number: " num
  echo $[ $num*2 ]    #函数最后一条命令的输出即为函数的返回值
}
result=$(doubleYou) #使用函数名即可调用函数,但如果需要得到函数的返回值,则需要象前述执行命令一样使用$(functionName)进行
echo "The double value is $result"


#!/bin/bash
#----从命令行获取参数----
function sum1 {
  echo $[ $1+$2 ]       #shell将函数看着mini-script执行,所以,此处的$1、$2相当于是调用函数时的命令行参数
}
if(($#==2))
then
  value=$(sum1 $1 $2)    #将命令行的两个参数传给sum函数。
  echo "$1 + $2 = $value"
else
  echo "Usage: add a b"
fi
#
#----使用全局变量传递参数----
function sum2 {
  echo $[ $val1+$val2 ]     #sum函数外定义的变量在函数内可见
}
read -p "Enter two number: " val1 val2
echo "$val1 + $val2 = $(sum2)"


#!/bin/bash
function factorial {
  if [ $1 -eq 1 ]
  then
    echo 1
  else
    temp=$[ $1 - 1 ]
    result=$(factorial $temp)
    echo $[ $result * $1 ]
  fi
}
read -p "Enter value: " value
fac=$(factorial $value)
echo "The factorial of $value is: $fac"

数据流编辑

我们会对文本数据进行大量的处理,目前可以使用交互式的文本编辑器如vim进行插入、替换、删除等操作。

但有些情况下这种交互式的工作方式不适合自动化处理,如我们要实时过滤从网络传来的数据然后再呈现给用户就不能停下来等交互式的命令。

我们可以预先定义处理规则,然后交由某种流编辑器自动进行处理,如sed(stream editor)

  1. 从输入中一次读取一行
  2. 按给定的规则对数据进行匹配
  3. 匹配成功的数据按给定的命令进行改变
  4. 输出新数据到标准输出


#s是替换命令,它将第一对斜线包括的模式字符串替换为第二对斜线包含的字符串,可以使用"
#----字符串替换----
echo "this is a test" | sed 's/test/big test/'
#The quick brown fox jumps over the lazy dog.
sed 's/dog/cat/' data.txt   #将data.txt文件中的dog全部替换为cat,注意data.txt不改变
sed '2s/dog/cat/' data.txt  #替换第二行
sed '2,3s/dog/cat/' data.txt  #替换第二、三行
sed '2,$s/dog/cat/' data.txt  #从第二行到最后替换
sed '/xxx/s/dog/cat/' data.txt  #含有xxx的行才替换
sed -e 's/brown/green/; s/dog/cat/w newdata.txt' data.txt   #如果有多个命令,则需要使用e选项,w标志将结果输出到新文件
sed 's!/bin/bash!/bin/csh!' /etc/passwd     #如果要替换的字符串中出现分隔符/,则将3个分隔符使用!/代替
#----行删除----
sed '3d' data.txt       #删除第三行
sed '2,$d' data.txt     #从第二行到最后行删除
sed '/xxx/d' data.txt   #含有xxx的行删除
#----行插入或添加----
echo "Test Line 2" | sed 'i\Test Line 1'    #行前插入行
echo "Test Line 2" | sed 'a\Test Line 3'    #行后添加行
sed '$a\This is a new line of text.' data.txt  #最后行添加
#----行改变----
sed '3c\This is a changed line of text.' data.txt           #改变第三行
sed '/xxx/c\This is a changed line of text.' data.txt       #含有xxx的行改变
#----字符变换----
echo "This 1 is a test of 1 try." | sed 'y/12a/45A/'        #对应的字符改变,如1变为4,a变为A


sed '/xxx/{N;s/\n/ /}' data.txt     #N用于组合两行。将含有xxx的行与其下一行组合为一行,将改行的回车替换为空格
echo "The cat sleeps in his hat." | sed 's/.at/"&"/g'   #.表示匹配任意字符除换行外,&表示找到的对象。将含有at的单词加上"",且截至到at
#将html文件的tag去掉,并删除空行
<html>
<head>
  <title>This is the page title</title>
</head>
<body>
  <p>
  This is the <b>first</b> line in the Web page.
  This should provide some <i>useful</i>
  information to use in our sed script.
</body>
</html>
#命令分别如下
sed 's/<.*>//g' test.html   #以<开始,以>结束,中间任意字符重复0到任意多次。有bug,看看title的内容去哪儿了?
sed 's/<[^>]*>//g ; /^$/d' test.html   #[^>]为反义,表明<>之间不能有>。然后删除空行:^表示字符串开始,$表示字符串结束

要进行强大的流编辑,还需要依靠正则表达式,请有需要时查阅相关文档。

实用的脚本

设当前目录homework下有linux、web、c等子目录用于存放学生提交的作业文件,同时还有一个backup目录下也有linux、web、c等子目录用于备份。

现将指定的课程作业以课程名称+日期为名压缩,并保存在backup目录下对应的课程名称目录中,且删除原始作业


#!/bin/bash
#将指定课程的作业以课程名称+日期为名压缩,并保存在backup目录下对应的课程名称目录中,且删除原始作业
if [ $# -eq 1 ]   #命令行指定了课程名称
then    
  coursename=$1   #得到课程名称
  backupDirectory=./backup/$coursename  #得到备份路径
  if ! [ -d $backupDirectory ]  #备份目录不存在则创建
  then
    mkdir -p $backupDirectory
  fi
  filename=$coursename-$(date +%y%m%d).7z   #以课程名称-日期.7z作为压缩备份文件名,
  if 7z a $backupDirectory/$filename ./$coursename    #执行压缩
  then
    rm -f ./$coursename/*   #压缩备份成功则删除原文件
    echo "Task is completed!"
  else                      #压缩不成功
    echo "Error!!!"
  fi
else    #未指定课程名称,给出用法
  echo "Usage: backup.sh courseName"
fi

在Linux这个自由、开放和免费的平台上,除了提供大量的应用软件外,还有许多的开发工具。本实验将学习使用GCC和make进行C/C++程序的开发。

GNU Compiler Collection-gcc

GCC原意为GNU project C and C++ compiler,及C/C++编译器。但由于其高效、稳定、易用以及跨平台,现在已扩展为多种语言如Objective-C、Fortran、Java等语言的编译器,即GCC代表GNU Compiler Collection。

一个C/C++源程序要能运行,即生成对应的可执行程序,需要经过4个步骤:预处理->编译->汇编->链接,GCC可以对这个过程进行非常灵活的处理。

Fedora已经预置了GCC,如果没有,请使用sudo dnf install gcc安装即可。

我们使用以下C程序为例进行学习


#include "stdio.h"
#define PI1 3.14
#define PI2 3.1415926
int main(){
  printf("Hello gcc!\n");
  printf("LiuHui found it: %4.2f, and ZuChongZhi updated it: %9.7f\n", PI1, PI2);
  return 0;
}

预处理(Preprocessing)是指对源程序中的文件包含、宏定义等进行处理的过程。使用命令gcc hello.c -o hello.i。可打开hello.i文件查看预处理结果

编译(Compiling)是对预处理后的文件进行语法和句法分析,尽可能找到不符合规范的地方,并给出警告或错误,并停止编译。

如果没有语法问题,则进一步将该文件生成为汇编(一种接近机器语言的低级语言)代码。

使用命令gcc -s hello.c -o hello.s进行,可打开hello.s查看。估计你也看不懂 :)

将源程序中的";去掉一个试试!

汇编(Assembling)即是将上一步的汇编程序翻译为目标机器代码的过程。目标文件完全由机器代码构成,通常有代码段和数据段两部分。

使用命令gcc -c hello.c -o hello.o将得到目标文件。现在用文本编辑工具打开hello.o文件将出现乱码,因为其为二进制代码而非ASCII码。

链接(Linking)即生成最后的可执行文件的过程,实际即为将程序中要使用的一些库文件链接起来(想想dll文件)。使用gcc hello.c -o hello则得到hello这个可执行文件,运行./hello试试。

实际应用中,我们通常只执行最后一步即可搞定 :)

大型项目构建工具-make

在实际开发中,很少只有一个C/C++源文件,也即作为项目,我们有许多的源文件并且组织在各个目录下。此时,对每个源文件进行上述的步骤就非常繁琐。

我们需要自动化的编译工具,这就是make。如何构建大型项目以及生成自动化编译配置文件我们暂时不管,下面我们以 sysstat 这个工具为例进行自动编译

Linux是一个自由、开放和免费的平台和系统。本实验将对网络、服务、安全、系统等方面的管理进行学习。

网络管理

接入Internet的设备必须有至少一块网络接口设备(有线或无线,无线又分为WiFi或4G等)。使用nmcli dip addressifconfig可以得到所有网络接口的信息。

一般地,RedHat系列的Linux中,有线以太网卡以en(EtherNet)开头,无线网卡以wl(Wireless Lan)开头,本地回路(loopback)以lo开头,虚拟网卡以vir开头

该设备又必须有一些基本的网络配置如:IP地址、子网掩码、网关、DNS服务器等等。

Linux可以让我们以图形、文本交互和文件配置的方式对这些网络信息进行配置(另外,我们也可以使用命令行交互方式即nmcli命令进行,因内容较多,请自行参考学习)。

点击网络图标,或进入系统设置->网络配置即可进行相应配置

在某些情况下,如远程登录、Linux作为服务器等,你所在的Linux环境没有图形界面,此时可使用文本方式即TUI(Text User Interface)

输入nmtui即可打开该程序,如果没有则可以安装。

所有的网络配置文件都在/etc/sysconfig/network-scripts目录下(以ifcfg-开头,然后是网卡名称),因此我们可以对该文件进行编辑。

动态配置则参见该文件即可,注意BOOTPROTO=dhcp以及ONBOOT=yes两项。静态配置一般如下:


BOOTPROTO="static" #静态配置 
ONBOOT="yes" #开机启用该设备
IPADDR=192.168.89.64 #静态IP地址
NETMASK=255.255.255.0 #子网掩码
GATEWAY=192.168.89.1 #默认网关
DNS1=8.8.8.8 #DNS服务器1配置,可添加多个DNS服务器

配置文件修改后请使用nmcli c reload重新加载连接配置


sudo ifconfig wlp2s0 down/up      #网卡禁用/启用
sudo ip link set down/up wlp2s0   #网卡禁用/启用
route -n  #显示路由(网关)信息
cat /etc/resolv.conf  #显示DNS服务器信息
ping www.baidu.com    #测试网络联通性,可学习其选项
mtr www.baidu.com     #路由追踪
netstat -natp   #查看活动的端口,ss -natp与之类似,且ss(Socket Statistics)为其替代
sudo iftop -i wlp2s0    #网络传输监视,该软件需额外安装,h为其帮助
cat /etc/hosts文件      #查看DNS本地解析文件
nslookup www.baidu.com  #DNS解析,dig www.baidu.com更详尽
rsync -a --delete ~/test/ ~/test-backup/    #将test目录全部同步到test-backup目录,首次运行将全部复制,以后只同步更改的内容。delete选项将删除发送端已没有而接收端还存在的文件。本地目录或远程目录可使用[email protected]:/home/test这种格式。
rdesktop 10.1.230.122   #使用RDP协议连接远程桌面            

服务管理

Linux服务器的主要任务就是为本地或远程用户提供各种服务,如Web、SSH、EMail、Ftp、Database等等。

这些服务由运行在后台的守护进程(daemon)来执行,一般在系统启动后就已经运行且准备好为响应用户的请求。

最特殊的守护进程是PID为1的系统初始化进程,它是其它守护进程的父进程。

当前的Linux系统一般使用先进的Systemd来初始化系统,也提供了对服务的控制和管理。

常用服务管理命令为:systemctl start/stop/restart/staus service-name,下面我们以周期性的计划任务服务crond这个系统服务为例:


systemctl status crond  #显示该服务的状态
systemctl stop crond    #停止该服务,可用systemctl status/is-active查看
systemctl start crond   #启动该服务
systemctl restart crond #重启服务,一般用于配置修改后

可使用systemctl -at service查看所有服务

服务的持久化是指服务是否在系统启动时自动运行。我们仍以crond服务为例,常用的命令如下:


systemctl is-enabled crond  #显示该服务是否自启动
systemctl disable crond    #禁止该服务的自启动
systemctl enable crond   #启动该服务的自启动

可使用systemctl list-unit-files -t service查看所有服务的持久化情况

无论用户是使用还是管理Linux,远程操作是常见的,也是方便的。Linux提供SSH(Secure SHell)这个系统服务来安全的传输远程数据。

当前一般都使用Open SSH Server这个开源的SSH服务软件,其守护进程名称为sshd(如果没有请使用sudo dnf install openssh-server安装即可),启动后即可使用SSH客户端MobaXterm等进行远程连接。

SSH服务的配置文件是/etc/ssh/sshd_config。注意:修改后需重启该服务。以下是一些简介:


Port 22   #默认22号端口为服务端口
ListenAddress 0.0.0.0 #默认任何IP都可连接,如设为127.0.0.1则只能本机登录
PermitRootLogin yes   #从安全角度考虑因设置为no
PasswordAuthentication yes  #是否允许口令登录。

SSH的安全认证可基于口令(一般)和基于密钥(更安全)。有关基于密钥的认证方式请查阅资料
我们还可以使用scp命令在本机和远程计算机之间进行文件复制

Web应用离不开Web服务器,Apache和Nginx是两种采用最多的开源Web服务器。下面我们以Nginx为例介绍Linux上Web服务的搭建和配置。


sudo dnf install nginx  #安装nginx
nginx -v                #查看nginx的信息如根目录、配置文件位置等。也可打开127.0.0.1得到相关页面。
#当前,Web服务只能本机访问,需要配置防火墙
sudo firewall-cmd --add-service=http --permanent   #配置防火墙允许http的流量并成为持久性规则
sudo firewall-cmd --reload   #重启防火墙使规则生效。此时其它计算机可访问。
systemctl enable nginx  #可选,设置为开机启动

查看/etc/nginx/nginx.conf配置文件,注意server小节的内容。
将自己的 网页文件 复制到根目录,访问看看。

作为IT学生,科学上网是必须的!姿势有很多,推荐SS。相关介绍请前往 SS WiKi 以及 shadowsocks实现原理

简单的说,SS分为服务器端和客户端,服务器端在海外,客户端在本机。本机有了,那海外的服务器在哪儿?

拥有一架 Google 的小飞机是一种怎样的体验 使用Google Cloud Platform(GCP)安装SSR+BBR教程

SSR是后来人添加了流量混淆功能,能增强GFW拦截我们科学上网的难度;
BBR是来自Google的拥塞控制算法,能提高我们科学上网的速度

安全管理

由于不同的体系结构、组成方式以及维护方式等,Linux系统在大多数情况下都比Windows系统安全,但这不意味着Linux就固若金汤。

我们可以通过以下配置来进一步提升Linux系统的安全性。

在服务器 BIOS 中禁用光驱、软驱、U盘等可引导的外部设备,并启用 BIOS 密码及 GRUB 密码来限制对系统的物理访问。

大多数Linux发行版允许您在安装过程中使用加密磁盘技术(一般采用加密的LVM逻辑卷管理器),这保证了Linux启动时输入密码才能读取硬盘数据。

对于重要的个人文件,还可使用Linux内置的开源加密软件OpenSSLGPG进行保护


openssl enc -des3/aes128/aes256 -k yourKey -e -in test.txt -out test.txt.aes   #以des3或aes256进行加密 
openssl enc -des3/aes128/aes256 -k yourKey -d -in test.txt.aes -out test.txt   #以des3或aes256进行解密
openssl dgst -md5/sha1/sha256/sha384/sha512 test.txt    #执行各种摘要 

一般地,我们安装Linux时没有进行手动分区,则系统只有两个挂载点及/(根分区)和swap(交换分区),这导致出现问题时我们的系统和数据都将受到影响。

为了稳定、性能以及安全考虑,建议进行以下分区:


/     #根分区,10G左右,是每个Linux系统必须要有的分区,是主文件系统挂载和其他文件系统挂靠的地方(/bin,/sbin, /lib, /etc, /dev 这五个目录不可与/所在的分区分开)。
/swap #交换分区,与内存大小一致即可
/boot #引导分区,1G,包含内核等文件,在日常系统运行中并不需要,只在启动和内核升级时候用到。独立后,即使主要的根分区出现了问题,计算机依然能够启动。
/var  #可变目录,50G,通常被用作缓存或者日志记录,读写频繁
/usr  #Unix system resource分区, Linux系统安装软件的地方,100G,除了系统的基本程序外,其它所有的应用程序多放在这个目录当中,最好划分的大一些
/home #用户目录,100G,个人数据或软件的所在地。独立出来可使得重新安装系统时选择不要格式化这个分区,重新挂载为/home就不会丢失数据
/tmp  #临时分区,10G,临时文件存放处,可定时清理

尽量始终保持系统内核、应用补丁及安全修复处在最新状态。目前的Linux系统基本已启动了自动更新机制,也可使用sudo dnf update/upgrade手动进行。

请记住:非必要的软件就不安装,非必要的服务就不开启!


dnf list installed    #列出已安装的软件包
sudo dnf remove xxx       #删除xxx软件
ss -antp              #查看打开的端口以确定那些网络服务不需要运行
systemctl list-unit-files –type=service | grep enabled  #查看开机运行的服务
systemctl disable service_name  #禁止某服务开机启动

SSH是Linux最常见的服务,以下的设置可考虑:


Port 8964               #更改默认的SSH端口
PermitRootLogin no      #不允许root用户登录
AllowUsers [username]   #只允许特定用户登录
ClientAliveInterval 60 #登录时间间隔60秒
PasswordAuthentication no #不使用密码而使用密钥认证(相关设置请查询资料)

Firewall防火墙是位于不同信任级别之间的控制和检测的硬软件,进出的数据必须经过Firewall,根据策略来决定允许还是禁止。

Linux提供了异常强大的防火墙设置。我们可以使用命令行配置工具firewall-cmd和图形界面工具firewall-config(需要安装)进行。

Firewall的配置涉及了较多方面,请自行查询相关资料学习。

SELinux(Security Enhanced Linux,安全强化Linux)是由美国国家安全局NSA发布并2002年正式集成到Linux内核中的强制访问控制的安全机制。

强制访问控制系统的用途在于增强系统抵御 0-Day 攻击(利用尚未公开的漏洞实现的攻击行为)的能力。所以它不是网络防火墙或 ACL 的替代品,在用途上也不重复。

举例来说,系统上的 Nginx 被发现存在一个漏洞,使得某远程用户可以访问系统上的敏感文件(比如 /etc/passwd 来获得系统已存在用户),而修复该安全漏洞的 Nginx 更新补丁尚未释出。此时 SELinux 可以起到弥补该漏洞的缓和方案。因为 /etc/passwd 不具有 Nginx 的访问标签,所以 Nginx 对于 /etc/passwd 的访问会被 SELinux 阻止。

该机制又让Linux的安全等级得到提高。安全性与便利性从来都是矛盾的,为了方便配置有人建议禁用 SELinux 功能,我强烈建议三思。

SELinux有三种运行模式:Enforcing(强制,默认配置)、Permissive(宽容,只会产生相应日志和警告)以及Disabled(禁用,不推荐)。

使用sestatusgetenforce可查看当前的状态模式。sudo setenforce enforcing/permissive可临时改变SELinux的运行状态。永久改变可编辑/etc/selinux/config文件进行模式修改(注意当从 Disabled 切换到 permissive 或者 enforcing 模式后需重启计算机生效)。

有关SELinux的使用和配置等请查阅SELinux 入门等相关资料!

审查日志能让自己对系统的状态和问题有全面的了解,一般位于/var/log目录下。需留意系统启动、验证、Web服务、数据库服务、SSH服务等日志文件。

系统管理

Linux系统有大量的开源、免费的软件可供使用,Red Hat系列(CentOS、Fedora等)使用RPM(Red Hat Package Manager)格式,另一个流行的发行版Debian使用deb格式。

我们要安装某软件,可能还需要其它软件的支持,以及存在依赖性。在RedHat系列中以前使用YUM进行管理,现在推荐使用DNF。

DNF包管理器对用户友好,内存占用低,依赖分析速度快。如果没有安装请使用yum install dnf进行安装。

常见dnf命令如下(常见软件仓库/更新源请参见 Linux配置小节):


dnf repolist all    #列出当前系统软件仓库(repository)。
dnf list installed  #列出已经安装的RPM包
dnf search shadowsocks  #在软件仓库中搜索某软件(可用于不知道具体软件名称时)
dnf install shadowsocks-qt5     #安装某软件
dnf reinstall shadowsocks-qt5   #重新安装某软件
dnf update yarn   #升级某软件
dnf remove yarn   #卸载某软件
dnf update    #升级所有系统软件包
dnf autoremove    #自动卸载孤立(不再使用)软件包
dnf clean all     #清理垃圾文件

作为一个强大的多用户OS,Linux允许多个用户登录系统并使用。为保证系统的安全和稳定,这些用户应该有不同的权限。

账户分为超级用户和普通用户,root用户即超级用户,具有绝对的权限。因此,即使只用一个用户,也建议再建一个普通用户使用系统,需要权限时使用sudo即可(临时提权,有限制和活动记录,具体配置在/etc/sudoers中)。

用户文件/etc/passwd对所有用户可读,包含用户名、口令(X)、用户ID(root固定为0,1-999为系统标准用户,1000即以上为普通用户)、组ID、Home目录等信息。

口令文件/etc/shadow只对root用户可读,且口令用SHA512进行了哈希(即使两个用户口令相同,也会因盐值不同而Hash不同)

常见用户管理命令(root权限):


sudo useradd haha  #生成haha用户,同时生成home目录(-M不生成home目录)
sudo passwd haha   #普通用户只能更改自己的口令
su haha            #切换到haha用户
exit               #返回到当前用户
sudo userdel -r haha  #删除haha用户,同时删除home目录、邮箱等

Linux系统的启动以及程序的运行是一个严谨、有序和复杂的过程。我们需要对系统的状态进行监控以便于优化。

以下是一些常见的命令(如没有请安装即可,还可参见一些基于Web的集成监控工具)


uptime    #系统运行时间及评级负载
htop      #top工具的升级版,系统总体信息
iostat -d 3    #磁盘I/O统计。磁盘性能需要注意,建议使用SSD
nload/iftop -i wlp2s0   #网络流量统计
systemd-analyze time    #系统启动时间统计
systemd-analyze blame   #列出是各服务占用的时间(blame-责任)