文章目录
快乐的 Linux 命令行
Chapter 1-15
-
注意以下几种
ls
[root@Nazure ~]ls -l ... [root@Nazure ~]ls -l . ... [root@Nazure ~]ls -ld * ...
其结果是一样的,其中①和②是一样的,
.
表示当前目录,且可以省略,就是列出当前目录下所有的文件和目录;*
是通配符,展开为当前目录下所有的文件和目录,如果不加-d
选项,因为ls
的特性,就会把目录内的文件列出来,而不是列出目录本身。 -
双引号控制展开:
如果你把文本放在双引号中, shell 使用的特殊字符,除了 $, \ (反斜杠),和 `(倒引号)之外,则失去它们的特殊含义,被当作普通字符来看待。这意味着单词分割,路径名展开,波浪线展开,和花括号展开都被禁止,然而参数展开,算术展开,和命令替换仍然执行。
-
为什么
echo this is a dog
会输出this is a dog
,因为默认的单词分割机制会将空格作为参数分隔符,也就是echo
有四个参数,分别是 this、is、a、dog。单词分割被禁止,内嵌的空格也不会被当作界定符,它们成为参数的一部分。一旦加上双引号,我们的命令行就包含一个带有一个参数的命令。
-
-
export
的作用:将局部变量“导出”为“全局变量”(标准叫法应该叫环境变量),在命令中使用与在配置文件中使用它的作用是一样的。Linux 中在 profile 或者 bashrc 或者其他类似的文件中设置环境变量时(比如PATH),如果没有export,那么只能在直接启动的 shell 中起作用,如果在当前 shell 下运行脚本或者直接启动一个子shell,因为实际上是局部变量,子shell看不见的。
-
Bash 和 shell 的区别:
-
Shell 类似于一个概念和标准,Unix Shell 是一个命令行解析器,或者说 Shell 为类 Unix 操作系统提供了命令行用户接口。
-
Bash 就是一款 Shell 程序,是 Shell 的实现。
-
-
从 IO 理解“任何东西都是文件”这句话。程序的运行结果输送到一个叫标准输出的特殊文件,默认情况下,这个文件与屏幕相关联。
-
>
是标准输出的专用重定向操作符,标准错误没有专用的重定向操作符。因此使用标准错误的文件流描述符。Linux 系统中,一个应用程序可以在这几个文件流上产生输出,其中0、1、2分别是标准输入、标准输出和标准错误。因此,重定向标准错误这么写:
ls -l /notExist/haha 2> ls-error.txt
因为不存在
/notExist/haha
这个文件夹,因此ls
命令将输出错误,由于进行了重定向,错误信息将输出到ls-error.txt
这个文件中。 -
管道操作符
|
,把一个命令的标准输出管道到另一个命令的标准输入。 -
管道符和重定向符都是将数据作为程序的标准输入。
rm
命令源代码中肯定不接受标准输入,而是接收命令行参数,删除相应的文件。作为对比,cat
命令是既接受标准输入,又接受命令行参数:$ cat filename ...file text... $ cat < filename ...file text... $ echo 'hello world' | cat hello world
如果命令能够让终端阻塞,说明该命令接收标准输入,反之就是不接受,比如你只运行
cat
命令不加任何参数,终端就会阻塞,等待你输入字符串并回显相同的字符串。 -
var
目录主要针对常态性变动文件,包括缓存(cache)、登录文件(logfile)以及某些软件运行所产生的文件,包括程序文件(lock file,run file),或者例如Mysql数据库的文件等。 -
ls
默认输出目录中的文件和目录信息,如果想输出目录本身的信息,使用选项-d
。
[root@Nazure ~]# ls -l /root
total 64
-rw-r--r-- 1 root root 46 Mar 15 17:30 lazy_dog.txt
-rw-r--r-- 1 root root 57 Mar 15 17:21 ls-error.txt
-rw-r--r-- 1 root root 47067 Mar 15 17:06 ls-output.txt
-rw-r--r-- 1 root root 7150 Mar 15 18:02 ls.txt
[root@Nazure ~]# ls -ld /root
dr-xr-x---. 5 root root 4096 Mar 15 18:23 /root
总结:ls
的参数如果是文件,则输出文件相关信息;如果是目录,则默认输出目录下的文件和文件夹信息。
file
命令用来确定文件类型
[root@Nazure ~]# file ls-output.txt
ls-output.txt: ASCII text
-
执行程序
-
启动时放到后台执行:
xlogo &
-
调回前台执行:先查询工作序号
jobs
,再使用fg %1
-
启动后放到后台运行:先查询工作序号
jobs
,再使用bg %1
-
终止程序:
Ctrl-c
-
停止程序:
Ctrl-z
,将前台进程停止并移到后台等待 -
kill
给进程发送信号,“杀死程序”。
-
-
shell 环境:
~/.bash_profile
:用户的私有启动文件,可以用来扩展或重写全局配置脚本中的设置。在该文件中可以设置这样一行
PATH=$PATH:$HOME/bin
这样相当于重写了在
etc/profile
文件中定义的PATH
变量,具体原理就是把原PATH
展开,然后追加$HOME/bin
,使用:
分隔。这样就可以将自定义的一些命令存到这个目录中。 -
在
~/.bashrc
中可以进行自定义命令的配置,如alias l.='ls -d .* --color=auto'
表示自定义命令
l.
,列出当前目录中以.
开头的文件夹和文件。 -
vim 的使用
-
软件包管理
CentOS:底层工具为
rpm
,上层工具为yum
- 列出所安装的软件包:
rpm -qa
- 确定是否安装了一个软件包:
rpm -q nano
- 显示所安装的软件包的信息:
yum info nano
- 列出所安装的软件包:
Chapter 16 存储媒介
-
设备名与挂载点
-
设备名:
/dev/sdc
、/dev/sdd
设备名称是与设备连接的位置相关的。举例来说,如果一个设备连接到第一个 IDE 连接器的第一个连接点上,则这个设备就是第一通道上的主设备,
dev/hda
就是第一通道上的主设备名。 -
挂载点:就是 Linux 文件系统下的一个目录。
-
-
/mnt 目录和 /dev 的区别
- mount 了才能读取内容,而直接访问只能读设备信息
- 好比看碟,你访问 /dev 相当于直接拿碟片用眼看最多你能看出来是个 CD 或 DVD;但插到光驱里读就能看到电影了。
- 很多设备的数据组织和 linux 的文件系统并不一样。没法直接读取,你要看到文件目录,你必须得按照一定的格式去解析设备里的文件。这就是 mount 干的事,它按照你指定的格式去读取设备里的数据。就是转化为 linux 自己的文件系统,这样才能解析并读取数据。
-
CD-ROM 与镜像
-
创建 CD-ROM 的镜像:
dd if=/dev/cdrom of=ubunto.iso
-
将多个文件创建成镜像:
genisoimage -o cd_rom.iso -R -J ~/cd_rom_files
-
可以将一个硬盘上的镜像文件挂载到文件目录树上,就像挂载一个真实的 CD-ROM 设备一样:
mount -t iso9660 -o loop myimage.iso /mnt/iso_image
-
dd
与wodim
:dd
作用是用指定大小的块拷贝一个文件,并在拷贝的同一时候进行指定的转换,“Using dd (instead of cdrecord and dvdrecord) to write bootable ISO images to DVD-RAM disks”。wodim
主要用于将 iso 文件刻录到光盘中。 -
md5sum
校验写入光盘的数据的完整性md5sum dvd- image.iso; dd if=/ dev/ dvd bs=2048 count= $ (( $ (stat - c "%s" dvdimage.iso) / 2048 )) | md5sum
-
Chapter 17 网络
-
SSH 与 SSH 的两种认证方式
Secure Shell (SSH) 是一种加密的网络传输协议,可以在不安全的网络中为网络服务提供安全的传输环境。SSH 通过在网络中创建安全隧道来实现 SSH 客户端与服务器之间的连接。虽然任何网络服务都可以通过 SSH 实现安全传输,但 SSH 最常见的用途包括命令行、登录和远程命令执行。
1.1 基于密码的安全认证
使用服务器自动生成的公钥-私钥进行认证,具体流程为:
1️⃣客户端发送连接请求
2️⃣服务器发送公钥 serv_pub_key(可能发生中间人攻击,稍后细讲)
3️⃣客户端输入密码并使用公钥 serv_pub_key 加密
4️⃣服务器使用私钥 serv_priv_key 解密得到密码明文,与存储的登录密码对比验证
5️⃣验证通过后,客户端生成会话密钥 sess_key(对称加密),使用 serv_pub_key 加密发送给服务器
6️⃣服务器使用 serv_priv_key 解密,得到 sess_key,随后使用 sess_key 进行会话加密。
中间人攻击
在以上流程中,如果第1️⃣步的连接请求被中间人拦截,中间人冒充服务器向客户端将自己的公钥 spy_pub_key 发送给客户端,此后客户端发送的消息都是通过这个公钥进行加密的,因此攻击者能够窃听所有会话内容。
中间人攻击的根本原因是 SSH 没有 AC 发放证书,客户端不能确定接收到的公钥就是期望服务器的公钥。
1.2 基于密钥的安全认证
首先客户端生成一对公钥-私钥,并将公钥存储在服务器上。
1️⃣客户端发送连接请求
2️⃣服务器发送一段随机的字符串,使用公钥进行加密后发送给客户端
3️⃣客户端使用私钥对密文进行解密,将解密后的字符串发送给服务器
4️⃣服务器将收到的字符串与生成的字符串对比,如果一致,则验证通过
风险点:在将客户端公钥 AC 放到服务器这一步至关重要,服务器需要核实 AC 的来源。因为 SSH 只验证客户端是否拥有与公钥匹配的私钥,只要接收的私钥与存储的公钥匹配即通过验证。
这样的话,一旦接受了恶意攻击者的公钥,之后攻击者使用私钥登录时,也会将其视为合法用户。
Chapter 18 文件搜索
-
locate
用于定位文件。 -
块设备文件(Block special device file)
字符设备文件(Character special device file)
-
使用
find
查找文件的一个例子,同时理解通配符展开。find ~ -type f -name "*.JPG" -size +1M | wc -l
*。JPG
之所以要加引号,是避免 linux 在这里将*
展开为当前目录下的文件夹和文件名。 -
find
的选项包括三种,分别是test
、operator
和exec
-
所谓文件和文件夹的“正确权限”
文件:0600,只有文件所有者拥有读、写的权限(不具有执行的权限)
目录:0700,只有目录的所有者拥有读、写、执行的权限。(目录的执行权限就是可以
cd
进去)
Chapter 20 正则表达式
-
^
在[]
里面和外面的含义不同,^[123]biu
表示匹配以 1/2/3 数字开头,后面为 biu 的文本;而[^123]biu
表示匹配含非 1/2/3 开头,后面为 biu 的文本。简而言之,在括号外表示定位开头,在括号内表示非。
-
.
和*
在 shell 和 regex 中的含义是不同的shell 正则表达式 * 当前操作路径下所有的文件和目录(?) 量词,出现0次或多次(任意次) . 当前操作路径所在目录 预定义类,表示除回车符和换行符之外的所有字符 这两个符号在正则表达式中称为元字符,元字符主要有
^ $ . [ ] { } - ? * + ( ) | \
。正如你所看到的,正则表达式中的一些元字符在 shell 进行展开时也具有特殊含义。当我们在命令行中传递包含元字符的正则表达式的时候,把元字符用引号引起来至关重要,这样可以阻止 shell 将它们展开。
-
区分 Shell 展开与 正则表达式匹配,如
ls /usr/sbin/[[:upper:]]*
是一个 shell 展开例子,与正则表达式没有关系。 -
元字符这个很玄乎的名字是什么意思?我的理解的就是具有功能的字符。正则表达式语言由两种基本字符类型组成:文本字符和元字符。文本字符就是表达一个字符,而元字符具有特殊的(功能)含义,比如
^
表示锚点,(
、)
表示分组等等,它们不是表达文本中有一个这样的符号。如果想取消它们的特殊含义,则需要使用
\
进行转义。 -
简单的理解标准正则表达式和扩展正则表达式,主要是元字符不同,BRE 的元字符有
^ $ . [ ] *
,除此之外,其他字符都是文本字符。ERE 在此基础上,增加了元字符( ) { } ? + |
。它们是可以通过转义字符进行转化的,比如在 BRE 中想进行分组,即需要使用
(
的作为元字符,需要进行转义(不转义的话对于 BRE 来说就是个普通字符),例如\([123]-file\)
,表示对匹配到的形如2-file
的匹配项打上一个分组标签。感觉 ERE 更简洁,因为在 ERE 中如果使用这些元字符就不用加反斜线进行转移了,
([123]-file)
。当然,不仅如此, ERE 还增加了一些好用的新特性。
Chapter 21 文本处理
sort
按字段排序,按 offset 排序,按数字大小排序等uniq
一般用于对sort
的结果去重。注意,要想使其生效,必须先排序,因为uniq
只删除相邻的重复行。
Chapter 22 启动一个项目
-
here document 与 echo 类似,都是将内容输出到标准输出中。在脚本中使用 here document 的好处在于,默认情况下会将引号当做文本,使其失去在 shell 中的特殊含义。
[root@Nazure bin]# foo="some text" [root@Nazure bin]# echo $foo some text [root@Nazure bin]# echo "$foo" some text [root@Nazure bin]# cat << EOE > "$foo" > EOE "some text"
从上面可以看出,echo 将引号视为需要展开的标志,对里面的内容展开后去掉引号输出。而对于 here document 来说,则将引号视为文本字符。
Here Document 更重要的特性是,Here documents 可以和任意能接受标准输入的命令一块使用 。
流程控制:if 分支结构
-
例子
FILE=~/.bashrc if [ -e "$FILE" ]; then if [ -f "$FILE" ]; then echo "$FILE is a regular file." fi else echo "$FILE does not exist" exit 1 fi exit
$FILE
的引用方式,引号不是必须的,这是为了防止空参数。使用引号,保证参数总是一个字符串。- 结尾的 exit,不传递参数时,退出状态默认为零。
-
test
/[[ ]]
选项:选项 功能 test -n 字符串 字符串的长度非零 test -f File 该『文件名』是否为文件(file)?(常用) test -f File 侦测该文件名是否具有『可读』的属性?
读取键盘输入
-
以
read
为例理解命令参数与接收标准输入,read
命令从标准输入中读取变量的值,并将其赋值给后面的参数,这句话不严谨,看例子。[root@Nazure ~]# read -p "Enter a num > " aNum Enter a num > 18 [root@Nazure ~]# echo $aNum 18
-p
是选项,打印后面紧跟的参数—Enter a num >,aNum
是另一个参数,作为read
读取到输入值后创建的变量的变量名。read
从标准输入中接收输入,这里从标准输入中接收到了 18 这个数字。
位置参数
先看一个非常简单的命令
ls -l /usr/local
ls
命令对应的脚本需要获取两个参数,分别是-l
、/usr/local
,也就是位置参数。
-
使用
shift
循环读取位置参数,相当于有一个指针指在位置参数中的一个,shift 一次就往后移动一次。#!/bin/bash # script to display all parameters count=1 while [[$# -gt 0]]; do echo "Argument $count = $1" count=$((count+1)) shift done
-
向 shell 函数传递参数,与 shell 脚本接收参数的方式是一样的。调用时
funcname a b
,这样写。