本文不是一个Linux操作系统的命令行手册!
在本文中,笔者试图通过一系列问答的形式,从应用者的角度,来帮助读者处理和解决在使用Linux系统中常见的一些问题和困惑。文中还加入了笔者在长期使用Linux系统过程中的一些感悟和经验,以及对于Linux系统的认知和理解。由于Linux系统相关内容实在是太多,笔者遇到的想要讨论的内容,如果比较复杂,可能会将其独立出来讨论,一般能方便明了的说清楚的,就在本文讨论,所以本文会持续更新相关的内容。
由于篇幅的限制,本文其实也是一个系列文件,大体分为三个部分:
- 概念篇: Linux系统相关基础和概念
- 系统篇: Linux系统本身系统管理和应用的相关问题
- 软件篇: 在开发和应用中,常用的相关支撑性软件和其使用方式
本片是概念篇,主要讨论下列问题和内容:
- 什么是Linux?
- 什么是操作系统?
- Linux系统中,人机交互是如何实现的(如何操作)?
- 什么是架构?
- Linux如何安装?
- Linux和Windows系统的主要区别是什么?
- Linux系统中那些文件夹是做什么的?
什么是Linux?
Linux不是一个操作系统,而是一类操作系统或者是一个操作系统家族和操作系统社区。Linux系统从技术上而言,其实只是一个开源的操作系统内核(Kernal),由于它的开放、灵活和高效,围绕着它。它本身原生的并没有类似于Windows或者Mac OS这一类操作系统的产品化的形态。这样的形态显示不利于应用和商业上的推广。针对这种情况,有一些以RedHat为代表的软件公司,围绕着Linux内核,开发和集成了相关的系统管理工具和常用应用软件,以更加完整的软件包的形式发布并提供给最终用户来使用,这种封装后的软件包一般称为”发行版”,它这个产品形态就更接近于我们更熟悉的操作系统了。
市面上常见的发行版有RedHat、CentOS、Debian、Forda、Unbentu、Manjaro等等,看起来眼花缭乱。但其实它们很多也是家族化的。它们最大的差异,其实是软件包的管理方式,其次是集成的软件包、主打桌面环境和更新策略。RedHat家族的主力包括RedHat(企业),CentOS(社区),Forda(桌面)和无数的衍生发行版,主要使用RPM包管理工具;Debian家族包括Debian、Ubuntu和其衍生发行版,它们使用DEB包管理工具;而ArchLinux、Majanro等等,它们主要使用Pacman。一般国内的喜欢RedHat系和其兼容系统。笔者个人比较常用Debian,如果作为服务器系统,那些衍生版都觉得大多数是没有必要的。
此外,市场中还有一些其他的操作系统如FreeBSD、Solaris、SCOUnix等等,虽然很多也是开源软件,但它们并不能算是Linux操作系统,而是应该属于它的近亲-Unix操作系统。 Linix和Unix在底层的系统设计上有一些差异,但它们的哲学逻辑和方法论其实是比较一致的,这导致了在系统应用层面,它们的差异很小(比如很多系统工具和命令的使用方式都是一样的)。但在软件应用层面,开发者可能不得不为它们开发或者编译不同的适用版本。
什么是操作系统
前面讨论了Linux是或者不是有一个操作系统,却没有明确定义何为操作系统。操作系统(OS Operation System, OS)这个词本身就是一个模糊的概念和定义,事实上,操作系统确实没有一个明确的定义和范畴。软件厂商、行业在不同的历史阶段,对操作系统的定义和理解其实都是不同的,所以不用太纠结其内涵和定义。
简单的理解,狭义的操作系统就是一个硬件抽象层,它的目的是将应用软件和硬件进行解耦。操作系统的规划和实现,是在 “任何大型复杂的问题,都可以并且应当划分为可以实现的众多更小更简单的问题来进行解决”, 这一通用认知哲学和方法论的理论指导下产生的。这其实也是现代工业体系的基础:即垂直的专业分工和协作可以带来整体的效率、可扩展性、可进化性和可持续发展。
操作系统将硬件和软件进行解耦之后,软件的可移植性变得可能。只要操作系统的支撑,应用软件可以不关心其真正运行的硬件平台,也可以正常运行,就可以在自己专注的业务领域持续优化和发展。
另外,在长期的发展过程中,人们发现,有很多通用的操作和处理,也可以抽象出来,作为公共的功能在操作系统的层面来进行提供。比如现在所有的操作系统都会内置TCP/IP协议栈软件。另外基于一些商业上考量,有些厂商也选择将一些常用的功能性软件内置集成在操作系统中,来提升其产品的竞争力,典型的案例就是微软在其Windows操作系统中,内置了IE浏览器软件,从而赢得了第一次浏览器战争。
一般认为,现代化的操作系统,应该提供下列的功能和模块:
- 计算
“计算”这个词其实有点抽象,过于技术细节化。其实就是提供一个应用软件能够执行和运行的环境。这个在技术上而言,主要就是包括对应用进程的管理,对CPU和内存等资源的调度和使用控制,多个应用程序和任务之间的运行协调等等。对其主要考量指标就是本身的稳定和可靠性、资源占用、异常处理、长期运行、可管理性等方面。
- 网络
在系统层面上,实现通用化的网络传输功能,如对TCP/IP等基础网络协议的支持。附加和周边特性还可能包括如多网卡、多IP地址、NAT和路由、网络聚会、SSL卸载等等。
- 存储
磁盘和文件系统的管理。包括磁盘管理,文件系统管理,文件管理等方面的内容。高级的存储管理功能可能还包括如网络文件存储系统,新的存储系统支持如NFS、SAN、ISCSI、IB等等。
- 安全:
提供用户对系统、文件、网络和应用的相关安全访问和操作的模型和框架。具体包括如用户和角色(组)管理、用户文件和执行授权、应用和服务安全、防火墙(网络安全)、应用和用户操作审计等。
- 应用
技术上而言,这些并不是操作系统应该关注的问题,但前面已经提到,很多是商业方面的考量。特别是对于普通用户,可以极大的方便系统的操作和使用。在典型的现代化操作系统中,这些内容可能包括以下几个方面:
— 系统工具: 系统内置的相关系统管理和监控,用户、文件、网络和网络配置操作的工具,很多都是开箱即用的
— 软件管理: 软件的安装,配置和运行管理(特别是服务程序)
— 开发和执行环境: 相关的编译器和工具
— 常用和标准软件: 特别对于桌面系统,比如浏览器、写字板、画图、日历、电子邮件客户端等等
— 人机界面: 人作为信息系统的管理和参与方,需要提供相关的机制来参与,一般称为人机界面(User Interface, UI),后面会深入讨论
Linux系统中,人机交互是如何实现的?
所有的信息系统都是为人类社会提供服务的,起码在现在的技术和应用环境中,人还是其中的一个重要的环节和参与方。因此,广义上而言,任何完整的信息系统,都会设计一个人机界面来让人可以参与到信息处理的过程当中。
所有的人机交互过程,都可以进一步抽象成为信息的输入和输出。现有常用计算机系统,涉及人机交互的输入的主要硬件实现形式是鼠标和键盘;而输出的硬件主要是显示器(视觉)和扬声器(听觉)。在操作系统和软件的层面,输入和输出的主要形式就是命令行界面(CLI)和图形界面(GUI)了。
按照第一性的原理,Linux默认的人机界面是命令行界面(Command Line Interface, CLI)。它的操作逻辑其实非常简单清晰,输入命令和参数-系统处理-输出结果。从技术上而言,CLI的优势很多,包括:
— 一致性:所有的工具和软件,都可以在一个终端界面(SHELL)中执行,而且在大多数情况下,它们使用和运行的方式也是类似的,大大降低了学习和熟悉的成本
— 资源占用: 显然,文本化的输入输出和后台化的执行操作,让CLI程序在系统执行层面的资源占用和执行代价非常小
— 方便远程执行: 由于输入输出的需要处理的信息很少,所以CLI在网络上执行操作,所需要付出的代价也非常低,就使其特别适合于基于网络进行远程操作和执行;Linux通常在网络上使用SSH,使用方式和本机的TTY基本上没有什么差别
— 脚本和自动化: CLI的输入是基于文本的,特别适合于编写脚本来实现操作的自动化。这一可以大大提高大规模多系统管理的效率
当然,CLI也有不合适和适用的场景。特别是一些需要进行可视化输入和输出的场合(比如CAD)。另外CLI对于普通的操作人员要求比较高,需要学习和熟悉相关的命令和参数。这样,就发展出了图形界面(Graphic User Interface)。这方面的典型代表就是Windows操作系统了。本质上而言,GUI就是输入信息、操作过程和处理结果的可视化和拟物(图形)化,大大降低了普通人使用计算机系统的学习成本和难度。这一点对于信息技术在现代社会的推广和普及功不可没。
这个大家都熟悉,这里不再赘述其优点。但笔者需要指出的是,对于某些操作任务,它的操作环节过多,而且如果遇到一些复杂的参数和配置,其界面逻辑也会非常复杂。所以,如果不考虑直观带来的易用性的前提下,其实GUI并不是特别适合于服务类的系统配置和管理的应用场景。这也是Linux系统的主要市场所在。当然Linux也可以提供GUI来开展应用,就是所谓桌面的系统,但这些确实不是Linux擅长和专注的领域。
还有一种文本化的图形界面(Text User Interface, TUI),它使用GUI的思想和逻辑,但全部使用文本和字符方式实现。 典型的代表就是原来DOS系统中的Norton Command(NC)。在某些特定系统管理和操作任务中,可以降低管理员的记忆和学习负担,并可以实现更高的操作效率,比如文件选择和操作等等。
笔者认为,这几种人机界面,并没有绝对的优劣高下,它们都是针对不同应用场合和场景的产物,是相互补充和协作的关系,最终的目标,都是提高系统管理和开展应用的效率。
什么是架构?
我们在使用Linux和安装操作系统应用程序中,经常遇到需要下载不同架构的软件包。比如Debian操作系统,就支持amd64、arm64、armel、armhf、i386、mips64el、mipsel、ppc64el、s390x等架构。当然,Debian只是一个发行版本,实际的Linux内核,可以支持的架构更多,比如IA64、龙芯、Alpha等等,这也说明了Linux内核和发行版操作系统之间的关系和差异。
这里的架构,其实指的是CPU的指令集。同一个应用软件,即使有相同的源代码,一般也需要针对不同的CPU架构来进行编译,然后才能运行在匹配架构的操作系统当中。而且一般复杂的应用软件,都有很多依赖的软件模块和第三方软件,这些也需要相同的CPU架构来支持。所以一个CPU架构,就是一套软件生态系统。
我们一般在日常中遇到的普通的桌面电脑、笔记本和服务器系统,都是X86架构,准确的说,在Debian的分类中,就是AMD64(64位版本兼容32位,兼容Intel)和I386(Intel 32位版本)。而现在又有常用的平板电脑、手机和嵌入式系统,它们一般都是Arm架构,也有几个子类别。
Linux系统如何安装?
以在一台普通的Intel桌面机系统为例,Linux系统的一般安装方式和过程是:
- 确定硬件配置,特别是CPU的类型、磁盘和网络状况
- 规划安装和配置信息,包括磁盘、网络、用户等
- 到发行版的网站,搜索并且下载相应架构的安装包,一般是一个ISO文件。一般如果有在线安装条件的话,可以选择比较小的网络启动和安装版本,否则选择完整版,它包含比较多的常用软件
- 找一个U盘(现在应该没有人刻光盘了)和写U盘软件,将ISO文件写入U盘
- 配置系统启动时使用U盘引导
- 插入U盘,启动计算机,顺利的话,就可以看到启动过程,并进入安装系统的程序
- 系统安装过程要配置的信息一般包括系统名称、磁盘、网络、用户、软件、启动程序位置等等
- 如果主要是用于服务器系统,建议不安装图形界面和桌面环境
- 系统安装完成后,会提示取出U盘,并重新启动系统
对于比较常见和没有故障的硬件,现在的Linux的硬件支持和安装过程的兼容性都是比较好的。只要做好规划和准备工作,不会有太多的问题。比较容易出问题的地方可能包括:
- 磁盘分区,尤其是需要支持多份操作系统的情况
- 启动位置,安装完成后,需要标识启动程序,如果配置不当,容易造成重启后无法进入系统
- 网络,尤其是需要手动配置网络的情况,网络不通畅,会影响到后续在线的软件安装
- 软件,没有选择后续一些可能需要的工具,如编译器、图形界面等等,后续也可以在线安装,但可能就比较麻烦了
现在一般的硬件,安装Linux操作系统,应该是不支持无头安装的。也就是说,初次安装系统,还是需要使用显示器、键盘(和鼠标)的。原来的苹果服务器操作系统的安装支持无头模式,就是你可以用一台笔记本电脑,使用火线连接服务器(不确定是否支持网络),在笔记本上启动安装过程。 如果是工业标准服务器,如DELL等,它提供远程管理工具,本质上就是一个硬件和网络化的KVM系统,应该也可以执行远程无头安装(笔者听说过但没有实践过)。 一般我们作为开发者和使用者,又不需要大规模和频繁的安装系统,偶尔操作就不用在意这些了。
Linux和Windows系统的主要区别是什么?
有很多人特别喜欢比较技术方面的差异和不同,比如比较Windows和Linux系统,各种功能,性能和指标的差异。其实笔者认为,这种比较的意义不是很大。任何技术和系统,都有它的适应场合和局限性,关键是匹配实际的应用场景,更好的理解和掌握其技术特性,更好的解决需求和问题就可以了。
所以,笔者觉得,与其比较技术细节,还不如首先了解和明确它们的基本理念上的差异。要用好Linux,就首先需要了解和认同Linux系统(源自Unix)的一些系统哲学和方法论。
这里尝试例举几个,大家可以体会一下:
- Everything in the shell, 终端万能
终端,和命令行的操作方式,完美的体现了“所有计算机程序都是输入-处理-输出”的抽象理念。
- Simple is best,简单就是好
尽可能的保持概念、逻辑和过程的清晰和简单,如果无法做到,就要考虑层次化和模块化。
- Everything is file, 一切皆文件
比如linux系统中,所有的磁盘、网卡、设备,都可以在文件系统中找到其逻辑映射。这给系统管理带来了很大的方便,所有的配置信息、系统设置都可以使用一致的方式来完成。
- Do One Thing, And Do Best, 一次做好一件事
Linux提供很多系统工具的功能都非常简单,专注于做好一个功能。然后通过功能的组合,来完成更复杂的任务。
- Text In, Text Out, 使用文本作为输入和输出
文本,是信息表示的标准。使用文本,可以兼容和连接不同种类的应用程序。
- Shell Is Program, Shell也是编程环境
在linux系统中,有很多任务,其实可以不用编程来解决的。使用系统提高的功能和工具,进行合理的组合,就可以来处理。
- Use Pipeline, 管道操作
Linux提供了几种管道操作的符号和模式,合理使用,可以大大提高操作效率。
例如:
// 查看nginx程序是否在运行
ps aux | grep nginx
// 将当前文件夹的内容写入文件
tree . > flist.txt
如何管理Linux系统?
系统管理的具体内容,在更详细的系统管理篇章会详细讨论。这里只讨论Linux系统管理概念的核心要点、一般流程和方法论。
单独的操作系统,是没有意义的,操作系统本质上是一个硬件抽象和软件支撑的桥梁,来解决模块化,通用化的应用程序对于计算(CPU和内存)、存储(磁盘)、网络(网卡)和交互(显示、输入和输出)等四大类的能力需求。
当然,操作系统本身也是软件,也需要高效稳定的运行,才能更好的为应用软件提供支撑和服务。就需要具备良好的可管理性和可运维性。
Linux系统的日常管理工作包括查看系统信息和状态、查看软件和进程运行状态、管理文件和文件系统、配置网络、配置用户和权限等等。经过长时间的发展和演进,这些工作都可以通过一系列成熟软件、工具和工作流程来帮助管理员快速高效的完成。
Linux基本上是为网络服务器系统设计,所以相关流程和方法,都是按照终端和远程管理方式设计的,一般不会建议使用GUI进行操作。我们通常在配置好网络之后,在远程使用SSH客户端来安全的连接主机系统,进入一个虚拟的终端界面,就可以以本机终端一样的方式,来进行管理和操作了。
Linux系统中那些文件夹是做什么的?
作为一个普通的Linux用户,特别如果还熟悉Windows系统,登录linux系统后,首先觉得不适应的应该就是其文件的组织方式了。
Linix系统文件的组织方式,其实是来源于Unix系统的,历史要早于源自DOS系统的Windows文件系统。所以从技术的历史和延续性角度而言,其实Windows系统才是一个“异类”。究其原因,就是Windows系统的文件是以磁盘设备(DOS)为核心来设计的;而Unix本身系统就是以虚拟的文件系统,磁盘和系统之间是挂载(Mount)的关系。理解了这个,就非常容易理解Linux系统的文件组织结构。
一个正常安装并且运行的Linux系统中,有一个完整的文件系统和相关的组织方式。和Windows系统不同,Linux文件系统只有一个单一的树形文件结构,没有用盘符分区的概念。但其实多个磁盘或者分区,都可以动态的挂载到指定的文件夹下。我们登录到Linux系统中,可以使用 ls / 命令,就可以看到其整体的文件结构了。其构成和约定的作用如下:
/ 操作系统根
/root root用户的默认文件夹
/boot 系统启动使用文件
/dev 设备文件夹,这基本上是一个虚拟文件夹,所有设备都通过文件进行映射
/sys 系统相关信息虚拟目录
/proc 进程信息
/bin 系统内置可执行命令二进制文件文件夹
/sbin 系统相关二进制文件
/lib 库文件,各种库文件,共享库文件
/run 进程id文件
/etc 配置信息文件夹,几乎所有系统和软件配置都在这里找
/mnt 挂载文件系统使用
/media 媒体文件,如cdrom挂载使用等
/tmp 临时文件
/usr 只读或者静态的用户和程序文件
/var 预计可变的文件,如log、工作数据等等
/opt 一般用于应用程序
/mnt 挂载文件系统使用
/home 用户主目录,支持多个用户,每个用户都有同名子文件夹
/srv 网站和服务数据
这些基本上是在Linux设计和创建时,参考Unix系统,引入的文件系统层次结构标准(File Hierarachical Structure)。管理和使用时,最好按照规范和最佳实践执行,减少沟通和运维成本,也可以避免不必要的问题和麻烦。
如果没有特别的原因,不要使用或者修改系统文件夹中的内容,也不要在根文件夹中创建和保存文件。运维和管理工作中最常用的文件夹包括/etc,几乎所有应用和系统相关配置都在这里查看或者修改;/var/logs是默认的系统和应用程序日志文件所在; 扩展的磁盘和分区,通常挂载到/mnt文件夹中的子文件夹中;还有笔者喜欢将手动安装和自己开发的应用程序,安装到/opt文件夹中;临时和工作文件夹使用用户的默认文件夹等等。
至此,关于Linux系统的基本理解和概念,就到这里告一段落。我们会在下一篇《系统篇》中,详细讨论后续的相关系统功能和管理方面的内容。