初识shell之系统命令基础
一 shell介绍
Shell 中文意思贝壳,寓意类似内核的壳。Shell是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务,简而言之就是只要能够操作应用程序的接口都能够称为SHELL。狭义的shell指的是命令行方面的软件,广义的SHELL则包括图形界面。
Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。
所以说,shell可以指代两层意思:
1、命令解释器
python语言 《==================》shell命令
python解释器《=================》shell解释器
操作系统《=====================》操作系统
计算机硬件《===================》计算机硬件
sh(Bourne Shell)是一个早期的重要shell,1978年由史蒂夫·伯恩编写,并同Version 7 Unix一起发布。
bash(Bourne-Again Shell)是一个为GNU计划编写的Unix shell。1987年由布莱恩·福克斯创造。主要目标是与POSIX标准保持一致,同时兼顾对sh的兼容,是各种Linux发行版标准配置的Shell,在Linux系统上/bin/sh往往是指向/bin/bash的符号链接。
dash (Debian Almquist shell)一种 Unix shell。它比 Bash 小,只需要较少的磁盘空间,但是它的对话性功能也较少。它由 NetBSD版本的Almquist shell (ash)发展而来,于1997年由赫伯特·许(Herbert Xu)移植到Linux上,于2002年改名为 dash。
//sh 遵循POSIX规范:“当某行代码出错时,不继续往下解释”。bash 就算出错,也会继续向下执行。
//sh 跟bash的区别,实际上是bash有没开启POSIX模式的区别。
//简单说,sh是bash的一种特殊的模式,sh就是开启了POSIX标准的bash, /bin/sh 相当于 /bin/bash --posix。
//在Linux系统上/bin/sh往往是指向/bin/bash的符号链接
// ln -s /bin/bash /bin/sh
我们可以SHELL实现对Linux系统的管理例如:
1. 文件管理
2. 用户与权限管理
3. 进程管理
4. 磁盘管理
5. 网络管理
6. 软件管理
2、shell脚本
Shell 脚本(shell script)是一种为 shell 编写的脚本程序。常说的shell通常都是指 shell 脚本,但shell和shell script是两个不同的概念。通常说“shell编程”都是指 shell 脚本编程,不是指开发 shell 自身。
GNU bash
Bash(GNU Bourne-Again Shell)是许多Linux平台的内定Shell,事实上,还有许多传统UNIX上用的Shell,像tcsh、csh、ash、bsh、ksh等等,Shell Script大致都类同,即命令大都通用。当您学会一种Shell以后,其它的Shell会很快就上手,大多数的时候,一个Shell Script通常可以在很多种Shell上使用。
bash是大多数Linux系统以及Mac OS X v10.4默认的shell,bash具有极强的可移植性,它能运行于大多数Unix风格的操作系统之上,甚至被移植到了Microsoft Windows上的Cygwin系统中,以实现windows的POSIX虚拟接口。此外,它也被DJGPP项目移植到了MS-DOS上。bash的命令语法是Bourne shell命令语法的超集。数量庞大的Bourne shell脚本大多不经修改即可以在bash中执行,只有那些引用了Bourne特殊变量或使用了Bourne的内置命令的脚本才需要修改。
bash的命令语法很多来自Korn shell (ksh) 和 C shell (csh), 例如命令行编辑,命令历史,目录栈,$RANDOM 和 $PPID 变量,以及POSIX的命令置换语法: $(...)。GNU bash作为一个交互式的shell,按下TAB键即可自动补全已部分输入的程序名,文件名,变量名等等。
posix:(你应该感谢这个posix标准的设定,才能让你学完一种shell例如bash这种,就可以在rockylinux、ubuntu上一模一样的用)
// 一:简单来说:
POSIX(Portable Operating System Interface,可移植操作系统接口),是操作系统为应用程序提供的接口标准。
简单的说, POSIX(主要是解决了应用程序在各个操作系统上兼容性这样一个普遍存在的问题。只要一个应用程序的开发是为了在一个实现了POSIX模式的操作系统上运行,那么这个应用程序就可以在所用实现了POSIX模式的操作系统上运行。
// 二:
//1、POSIX定义
POSIX: Portable Operating System Interface of Unix.,可移植操作系统接口。X表示其是对Unix API的传承。
POSIX标准由IEEE(电气和电子工程师协会)发布,定义了操作系统应该为应用程序提供的接口标准,是IEEE为要在各种UNIX操作系统上运行软件而定义的一系列API标准的总称。
简单可以理解POSIX标准是为操作系统设计API时遵循的规范,一套规范的系统调用集。
//2、POSIX的诞生/解决的问题
POSIX的诞生和Unix的发展是密不可分的。当年最早的Unix,源代码流传出去了,加上早期的Unix不够完善,于是之后出现了好些独立开发的与Unix基本兼容但又不完全兼容的OS,通称Unix-like OS。这样版本混乱的情况导致相互之间的竞争和不兼容之处越来越多,给软件的可移植性带来很大困难,对Unix的发展极为不利。
为了提高兼容性和应用程序的可移植性,结束混乱局面,IEEE提出了POSIX标准,POSIX在源代码级别上定义了一组最小的Unix(类unix)操作系统接口。 这套标准涵盖了很多方面,比如Unix系统调用的C语言接口,shell程序和工具、线程和网络编程等。POSIX标准意在期望获得源代码级别的软件可移植性。为一个POSIX兼容的操作系统编写的程序,可以在任何其他POSIX操作系统上编译执行。
POSIX现在已经发展成为一个非常庞大的标准族,并不局限于Unix, 一些其他的操作系统,如Microsoft windows NT, Linux等都支持或者部分支持POSIX标准。
//3、POSIX标准的思路
问题: 不同操作系统内核为同一功能提供的系统调用(函数)是不同的,例如创建进程,linux下是fork函数,windows下是createprocess函数,如果在Linux下写了一个程序用到了fork函数,要往windows上移植就得把源代码里面的fork通通改成createprocess,然后重新编译。
解决方法: 定义POSIX标准, linux和windows实现基于POSIX标准,提供同样的接口,例如定义创建进程的接口为posix_fork(示例名/非真实名字), 且linux和windows都把各自创建进程的调用封装成posix_fork,都声明在unistd.h里。 这样程序员编写应用时,只需包含unistd.h, 调用这个POSIX标准中定义的API接口: posix_fork函数,即可实现源代码级别的可移植。
二 shell交互式环境
登录用户后进入解释器bash的交互式环境,可以敲命令,交互式环境的命令提示符如下
[root@xxx ~]# #号代表超级管理员用户对应的命令行
[root@xxx ~]$ $号代表普通用户对应的命令行
root==>当前登录的用户
@=====>分隔符
xxx==>主机名
~====>当前所在的路径
// 创建普通系统用户
useradd egon
// 交互式设置密码
passwd egon
// 非交互式设置密码
echo "123" | passwd --stdin egon
三 shell命令语法
三部分组成
- 1、命令:要执行的操作(必选)
- 2、选项:如何具体执行操作,通常以 -, –, +开头(可选)
- 3、参数:具体操作的对象(可选)
ps:unix认为命令运行完毕后没有提示便是最好的提示,即结果正确,linux继承unix的优良传统
例1
ls
ls /root
ls -l /root
例2
[root@rockylinux ~]# date
Fri Mar 15 22:24:38 CST 2024
[root@rockylinux ~]# date +%F
2024-03-15
[root@rockylinux ~]# date -s 22:26:00
Fri Mar 15 22:26:00 CST 2024
[root@rockylinux ~]# date
Fri Mar 15 22:26:01 CST 2024
[root@rockylinux ~]# data -s "2024-11-11 11:11:11"
-bash: data: command not found
[root@rockylinux ~]# date -s "2024-11-11 11:11:11"
Mon Nov 11 11:11:11 CST 2024
补充安装语言包:支持中文
yum install glibc-langpack-zh # rockylinux
如果安装过程中报错,大概率跟时间有关系,把你的事件用date -s "年-月-日 时:分:秒"设置一下
Curl error (60): SSL peer certificate or SSH remote key was not OK for https://mirrors.rockylinux.org/mirrorlist?arch=x86_64&repo=BaseOS-9 [SSL certificate problem: certificate has expired]
安装完语言包之后,设置一下,就可以展示中文了
[root@rockylinux ~]# export LANG=zh_CN.UTF-8
[root@rockylinux ~]# date
2024年 03月 15日 星期五 22:35:00 CST
例3
rockylinux
[root@rockylinux ~]# cat /etc/redhat-release
Rocky Linux release 9.3 (Blue Onyx)
[root@rockylinux ~]# uname -r
5.14.0-362.8.1.el9_3.x86_64
[root@rockylinux ~]# uname -m
x86_64
[root@rockylinux ~]# uname -a
Linux rockylinux 5.14.0-362.8.1.el9_3.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Nov 8 17:36:32 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
[root@rockylinux ~]#
四 bash解释器特性
- 命令和文件自动补全 注意:Tab只能补全命令和文件
[root@localhost ~]# ls /etc/sysconfig/network-scripts/ifcfg-ens33
- 快捷键
^c 终止前台运行的程序 ^l 清屏 ^a 光标移到命令行的最前端 ^e 光标移到命令行的后端 ^r 搜索历史命令,利用关键词 Alt+. 引用上一个命令的最后一个参数,等价于!$
- 历史命令
// 1、查看历史命令 [root@xxx ~]# history // 2、清空历史命令 [root@xxx ~]# history -c // 3、历史命令保存文件:cat ~/.bash_history // 4、历史命令默认保存1000条,可以修改/etc/profile中的HISTSIZE=2000 // 5、查找历史命令并运行 (1)光标上下键 (2)^r //搜索历史命令(输入一段某条命令的关键字:必须是连续的) (3)!220 //执行历史命令中第220条命令 (4)!字符串 //搜索历史命令中最近一个以xxxx字符开头的命令,例如!ser (5)!$ //引用上一个命令的最后一个参数 [root@xxx home]# ls /root /home [root@xxx home]# cd !$ cd /home [root@xxx home]# ls /root /home [root@xxx home]# touch !$/file1 touch /home/file1
- 别名
别名 # alias //查看系统当前的别名 ll='ls -l --color=tty' # alias egon='ls /etc/sysconfig/network-scripts/' //建立别名 # unalias egon [root@xxx ~]# grep root /etc/passwd // 默认有颜色 [root@xxx ~]# alias grep alias grep='grep --color=auto'
五 命令查找优先级:
bash shell查找命令顺序:
==>以路径(绝对路径,相对路径)开始命令,例如:/bin/ls 或 cd /bin; ./ls
==> alias
==> Compound Commands复合命令
==> function
==> build_in,如cd,kill,pwd、alias、echo等,可以用"type -a 命令"查看
==> hash:命令的本质是文件,将命令缓存到内存中,下次直接从内存取
==> $PATH,环境变量,查看环境变量echo $PATH,例如/bin/ls
==> error: command not found
复合命令例如
for((i=0;i<=3;i++))do echo 123;done
函数例如
function f(){ echo 123; },注意{}左右两边有空格
# ps:查看命令的位置:which 命令
六 查看帮助信息
1、man手册
// 1、简单使用
man 命令
// 2、详解如下
man 手册名,例如man ls
搜索:/-h n N
技巧一:按章节来查找,常用的是1(命令用法),5(文本规范),8(系统管理命令)
/usr/bin/passwd 命令,修改用户密码 man 1 passwd
/etc/passwd 保存用户信息的文件 man 5 passwd
/etc/exports man exports man 5 exports
技巧二:按关键字检索(适合记不住手册的全名时使用)
man -k "_selinux" //手册名或手册描述中包含关键字_selinux
注:从whatis数据库里找(# makewhatis)
技巧三:在所有章节中查询
# man -a passwd
# man -f passwd
2、–help或者help命令
命令 --help
help 命令
// 例1
[root@xxx ~]# ls --help
用法:ls [选项]... [文件]...
ls 常见选项
-a all,查看目录下的所有文件,包括隐藏文件
-l 长列表显示
-h human 以人性化方式显示出来
-d 只列出目录名,不列出其他内容
-t 按修改时间排序
-r 逆序排列
-i 显示文件的inode号(索引号)
3、info 非常详细的显示命令的说明信息
4、官方手册
5、 chatgpt、google、bing
七 常用命令
设置主机名
[root@iZm5e59rizbgmmp4net6zbZ ~]# hostnamectl set-hostname aliyun // 退出重新进入即可看到
设置默认启动级别
[root@iZm5e59rizbgmmp4net6zbZ ~]# systemctl set-default graphical.target // 图形界面
[root@iZm5e59rizbgmmp4net6zbZ ~]# systemctl set-default multi-user.target // 字符终端
查看ip地址(设置ip地址会在网络配置章节里详细介绍)
# 查看
ifconfig # rockylinux、ubunt都需要安装net-tools才能用ifconfi
ifconfig eth0 # 也可以执行ip a show eth0
用date命令操作时间
date --help
date "+%Y_%m_%d %H-%M-%S" # 查看时间
date -s "2018-05-17 09:51:50" # 设置时间
两种时间
1、系统时间:我们刚刚用date -s设置的是系统时间
2、硬件时间:存在CMOS中,开机时会读入内存作为系统的初始时间
如果刚date -s 设置完时系统立即崩溃,系统还没来得及将刚改的时间写入CMOS中,则本次设置无效
为了解决了改问题,可以在date -s之后理解执行hwclock –w # 这个命令强制把系统时间写入CMOS。
用timedatectl命令操作时间
#1、查看时间, timedatectl # 等同于 timedatectl status [root@localhost ~]# timedatectl status Local time: Sun 2024-04-14 22:03:06 CST # 即locat time,表示当前系统的时间、你所在时区的当前时间 Universal time: Sun 2024-04-14 14:03:06 UTC # 世界标准时间 RTC time: Sun 2024-04-14 14:03:06 # 硬件时钟的当前时间,也被称为实时时钟(Real-Time Clock) # 硬件时钟与你的CST差8h,系统会自动转换 Time zone: Asia/Shanghai (CST, +0800) # 系统当前时区 System clock synchronized: yes # 系统已经通过时间服务器同步了时间 NTP service: active # ntp服务(客户端)处于活跃状态 RTC in local TZ: no # 硬件时钟(RTC)是否设置为本地时间,如果设置了timedatectl set-local-rtc 1,这里就会显示yes # 在centos7.9上查看的结果有的字段名不一样,解释如下 “NTP enabled”,表示网络时间协议(NTP)是否启用。NTP主要用于同步系统时间,保持系统时间与全球标准时间一致。 “NTP synchronized”,表示系统时间是否已经通过NTP进行了同步。 “RTC in local TZ”,表示硬件时钟(RTC)是否设置为本地时间。如果设置了 timedatectl set-local-rtc 1,这里就会显示“yes”。 “DST active”,这表示你的系统是否正在使用夏令时。 #2、设置时间 timedatectl set-time “YYYY-MM-DD HH:MM:SS” # 如果开启了ntp则设置失败 #3、列出所有时区 timedatectl list-timezones #4、设置时区 timedatectl set-timezone Asia/Shanghai # 可以tab键补全时区 #5、将硬件时钟与本地时钟一致(不建议这么做,还是应该保持默认的让硬件rtc与utc保持一致) timedatectl set-local-rtc 1 # 设置为1代表让rtc硬件时钟读取本地时区的时间,设置为0代表读取utc时间,建议设置为0 #6、是否NTP服务器同步 timedatectl set-ntp yes # yes或者no
重启
shutdown -r 10 // 10分钟后重启
shutdown -r 0 // 立即重启
shutdown -r now // 立即重启
shutdown -r 11:30 // 定点重启
init 6 // 立即重启
reboot // 立即重启
关机
shutdown -h 10 // 10分钟后关机
shutdown -h 0 // 立刻关机
shutdown -h now // 立刻关机
shutdown -h 11:30 // 定点关机
halt // 立即停止系统,需要人工关闭电源
poweroff // 立即停止系统,并且关闭电源
取消正在进行的关机或重启
showdown -c
注销登录的账号
exit
logout
ctrl+d