Bash,正則表達式,vim,擴展權限

文本的主要內容爲,bash特性說明,bash編程基礎,包括變量,邏輯與算術運算,腳本的編寫執行;
正則表達式,grep,vim,文本與文件過濾命令,以及特殊權限與FACL

一、Bash

1. 命令hash

我們之前有介紹,之所以用戶能夠在執行命令時不輸入全部的路徑1,是因爲bash會根據一個叫做PATH的環境變量中提供的字符串去對應的路徑下搜索可執行程序。其值一般爲:

[root@localhost ~]# echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

這個搜索過程顯然需要花費時間,爲了節省這個時間,bash會將執行過的程序的路徑保存在內存中的特定位置,下次再次執行時可直接從該位置搜索,若搜索到則直接使用,不必再去文件系統中查找。而由於保存的內容是使用散列存儲,其在查找時的時間複雜度爲O(1)O(1),效率極高。

該存儲方式又叫做哈希(hash),故相應命令被稱爲hash

hash

該命令是bash的內建(builtin)命令,可管理bash此前生成的哈希表。該命令用法較爲簡單。

查看命令哈希的結果:
[root@localhost ~]# hash
hits	command
   1	/usr/bin/startx
   1	/usr/bin/tail
  14	/usr/bin/vim
   1	/usr/bin/expr
緩存的結果是以鍵值對(Key-Value)的形式顯示,hits表示命中次數,command表示命令路徑,其基名就是我們執行的命令。
清空哈希表
[root@localhost ~]# hash -r
清空指定條目
[root@localhost ~]# hash -d COMMAND

2. Bash配置文件

在介紹配置文件之前, 先介紹一款文本編輯器,以作編輯之用。

nano

nano是一款輕量級的文本編輯器,相當於Windows上的notepad(記事本),可以直接通過nano後跟文件名的方式使用,若文件名不存在,則將會新建該文件(若選擇保存),其打開界面如下:
nano界面

這是一個全屏編輯器,上方顯示了軟件版本以及當前文件,下方爲相關操作,如Ctrl+X爲退出等。

bash配置文件

Bash作爲最常用的shell程序之一,他的配置文件有多個,我們一般將其分爲兩類:

bash配置文件

  • profile類:爲交互式登錄的shell進程提供配置
    • /etc/profile
    • /etc/profile.d/*.sh
    • ~/.bash_profile
  • bashrc類:爲非交互式登錄的shell進程提供配置
    • /etc/bashrc
    • ~/.bashrc

雖然我們一般習慣如此去說明,事實上不論是登錄還是非登錄shell,在運行時都會讀取這兩類文件。

由於我們在命令行中的配置雖然可以立即生效,但是作用域僅爲當前進程,而若要其永久有效,就需要將配置寫入配置文件中。

另外,由其位置可知,/etc/中的配置對所有用戶有效,而用戶家目錄中的配置僅對當前用戶生效。

先回顧一下登錄式shell與非登錄式shell

  • 登錄式Shell:正常通過某終端登錄、su -[l] USERNAME進行的用戶切換
  • 非登錄式Shell:圖形終端下打開的命令窗口(僞終端)、自動執行的shell腳本、su USERNAME執行的登錄切換
兩類文件的一般功能
profile類文件
設定環境變量
運行命令或腳本
bashrc類文件
設定本地變量
定義命令別名

如,root/.bashrc內容爲:

# .bashrc

# User specific aliases and functions

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'

# Source global definitions
if [ -f /etc/bashrc ]; then
	. /etc/bashrc
fi

該文件定義了命令別名,而後讀取/etc/bashrc文件2

對於登錄式shell與非登錄式shell,他們讀取配置文件的順序不同:

  • 登錄式shell
/etc/profile
/etc/profile.d/*.sh
~/.bash_profile
~/.bashrc
/etc/bashrc
  • 非登錄式shell
~/.bashrc
/etc/bashrc
/etc/profile.d/*.sh
使用示例
  1. 添加用戶別名,cls=clear,當前用戶作用範圍,使其在每次登陸都有效
    [root@localhost ~]# nano .bashrc
    
    在其後添加一行:
    alias cls = 'clear'
    
  1. 使用戶在登陸系統時顯示當前時間,只對當前用戶生效
    [root@localhost ~]# nano .bash_profile
    
    在其後添加一行:
    echo "Hello,Welcome to our system.It is `date`."
    

修改了配置文件後,將在下次啓動新的shell進程時生效,若要立即生效,可通過source命令通知bash重新讀取。

source

該命令用於通知當前shell讀取或執行給定的配置文件,其後直接跟配置文件即可,如:

[root@localhost ~]# source .bashrc

另外,source可以簡寫爲.(點號),以下命令與上方命令等價:

[root@localhost ~]# . .bashrc

二、Bash編程

1. 變量

變量(Variable) 相信大家並不陌生,其實質上就是一段命名的內存空間。而在bash中,同樣支持變量的概念。

bash中的變量類型

變量類型 說明
環境變量 作用域爲當前shell進程及其子進程
本地變量 作用域爲整個bash進程
局部變量 作用域爲當前代碼段(通常指函數)
位置變量 $1,$2,…用於讓腳本在腳本代碼中調用通過命令行傳遞給它的參數
特殊變量 保存某些特殊數據3
特殊變量
$0: 腳本名稱本身
$?: 上一條命令的執行狀態
  • 狀態用數字表示:0-255
  • 成功:0
  • 失敗:1-255
$$:腳本運行的當前進程ID
$!:Shell最後運行的後臺進程的PID
$#: 參數數量
$*: 所有參數的一個字符串
$@:所有參數單獨作爲每個字符串
$1、$2…:位置變量,對應第一、第二個參數
關於$@與$*的區別:
只有在雙引號中體現出來。假設在腳本運行時寫了三個參數(分別存儲在$1 $2 $3)則"$*" 等價於 “$1 $2 $3"(傳遞了一個參數);而“$@" 等價於 “$1” “$2” “$3”(傳遞了三個參數)

變量聲明

bash中變量的命名規則同其他語言類似,變量名只能包含數字、字母和下劃線,而且不能以數字開頭,另外,變量賦值時不能使用$。

本地變量的聲明

bash爲弱類型,故在聲明變量時不必指定變量類型(但這不代表這些變量沒有類型),可直接使用如下形式聲明變量:

[set] VARNAME=VALUE
	set可省略

使用不帶參數的set命令可查看系統已定義的所有變量

只讀變量的聲明

readonly VARNAME
或
declare -r VARNAME

在聲明時指定readonly,或使用declare -r,可聲明只讀變量(常量),由於其在聲明後不可更改內容,需要在聲明時進行初始化。

環境變量的聲明

export VARNAME=VALUE
或
VARNAME=VALUE; export VARNAME
或
VARNAME=VALUE; declare -x VARNAME
或
declare -x VARNAME=VALUE
Tips;
在同一行執行的多條命令中間可使用;(分號)隔開
環境變量的查看
printenv
env
export
declare -x

環境變量對當前shell及其子shell都有效

局部變量的聲明

local VARNAME=VALUE

僅對局部代碼生效

變量的引用

  • ${VARNAME} 不會引起混淆的話,{}可省略
  • “” 弱引用,其中的變量引用會被替換爲變量值
  • ‘’ 強引用,其中的變量引用不會被替換爲變量值,而保持原字符串

2. 邏輯運算

與(AND)

“與”表示“並且”之意,即兩種事件都發生,使用 && 表示,其運算結果爲

  • 1 && 1 = 1
  • 1 && 0 = 0
  • 0 && 1 = 0
  • 0 && 0 = 0

即二者都爲真(True),結果才爲真(False),否則爲假

或(OR)

“或”表示二者任一即可,使用 || 表示,其運算結果爲

  • 1 || 1 = 1
  • 1 || 0 = 1
  • 0 || 1 = 1
  • 0 || 0 = 0

即二者都爲假,結果才爲假,否則爲真

非(NOT)

“非”表示“不”,取相反結果之意,這是一個單目運算符,使用 ! 其運算結果爲

  • ! 1 = 0
  • ! 0 = 1

邏輯短路

概念

由於“與”和“或”運算時自左而右的,加之其運算特性,我們可以得出如下結論

  • 若且(AND)運算的第一個運算數(Operand)爲假,結果一定爲假;
  • 若或(OR)運算的第一個運算數爲真,結果一定爲真;

如此則不必再去計算其二個運算數(或表達式)的結果,可直接得出最終結果,這種運算方式成爲短路運算,也叫作邏輯短路。

應用

通過這種特性,在bash中可是實現類似if條件判斷的處理。

我們知道,程序在執行完後會返回一個執行狀態,用於標識程序執行成功與否,使用0標識執行成功(即“真”),非0則標識執行失敗(即“假”)

可通過判斷該狀態返回值,對不同的結果(成功或失敗)處以不同的操作,如

查看user1是否存在,若存在,則輸出其信息,否則創建之:

id user1 2> /dev/null || useradd user1

可以組合多個這樣的命令以實現更復雜的控制

德摩根定律

該定律引用很廣泛,此處也將其列出
ABAB \overline{A \bigcap B} \equiv \overline{A} \bigcup \overline{B}

ABAB \overline{A \bigcup B} \equiv \overline{A} \bigcap \overline{B}

3. 算術運算

由於bash是弱類型的語言,其聲明的變量默認爲字符,運算法則默認也是按照字符運算進行的,若要使其進程算術運算,可使用如下幾種方式:

  • let VAR = ARITH_EXPR
  • VAR = $[ARITH_EXPR]
  • VAR = $((ARITH_EXPR))
  • VAR = $(expr ARITH_EXPR)

若欲計算變量A與變量B的和,以上表示的實現爲:

#let VAR = ARITH_EXPR
	let C = $A + $B
#VAR = $[ARITH_EXPR]
	C = $[$A + $B]
#VAR = $((ARITH_EXPR))
	C = $(($A + $B))
#VAR = $(ARITH_EXPR)
	C = $(expr $A + $B)
	C = `expr $A + $B`

如,計算user1,user2,user3用戶的UID之和

#!/bin/bash

uid1=`id -u user1`
uid2=`id -u user2`
uid3=`id -u user3`

uid_sum=$[$uid1 + $uid2 + $uid3]

echo "The sum of uid if $uid_sum."

4. 運行腳本

同其他編程不同,所謂的bash編程,調用的是系統上已有的程序命令,通過bash內置的變量、流程控制等機制實現的。

程序的執行方式
  • 編譯執行
    由源代碼直接一次性編譯爲而進行文件,可直接執行
  • 解釋執行
    程序文件內核無法直接理解,需要外部程序解釋源文件,逐條執行

代碼的源文件問文本格式,而內核只能執行二進制格式文件,故直接執行該文件內核是無法理解的,而bash是解釋執行的,需要爲其程序文件執行一個解釋器。

在程序文件內容的最開始處使用以 #! 開頭,後跟解釋器程序路徑的字符串來通知內核,使用該程序對文件進行解釋執行,而不是直接執行,這個字符串被稱爲 Shebang 。上文程序的第一行就是Shebang。

若不指定,則腳本無法直接執行,但可以明確指定解釋器,將該腳本文件當做參數讓解釋器執行,如上面的文件爲:

uid1=`id -u user1`
uid2=`id -u user2`
uid3=`id -u user3`

uid_sum=$[$uid1 + $uid2 + $uid3]

echo "The sum of uid if $uid_sum."

可使用bash SCRIPT_NAME執行之

另外,默認新建的文件是沒有執行權限的,若要直接執行,則需要爲其賦予執行權限:
chmod +x /PATH/TO/SCRPTE

三、正則表達式

0. 概念

正則表達式(REGular EXPression,REGEXP)使用單個字符串來描述、匹配一系列匹配某個句法規則的字符串的機制。它將一些字符作爲元字符(Meta Characteristic) 用於標識一類字符或用於特殊限定,而不是標識其原有的字面意義。

在進行文本匹配時,我們所寫的匹配表達式被稱爲模式(Pattern) ,而在Linux中,最常用的支持正則表達式的程序爲grep家族程序,根據其劃分,又分爲:

  • BRE(Basic RegEx),基本正則表達式
  • ERE(Extended RegEx),擴展正則表達式

在介紹正則表達式之前,前介紹grep的用法

1. grep、egrep、fgrep

這三個命令類似,都用作文本過濾,grep(Global Search Regular EXpression and print out the line)默認使用BRE,egrep默認使用ERE,fgrep模式不支持REGEXP,f爲fast之意。

由於以上三個命令可以使用參數而達到與彼此相同的效果,故而此處以grep爲例進行說明,其用法如下:

grep [OPTIONS] PATTERN [FILE...]
	[OPTIONS]
		-i			ignore-case 忽略大小寫
		--colour=auto
				將匹配到的字符高亮顯示,默認命令別名開啓
		-v			反向匹配,顯示沒有被模式匹配到的行
		-o			只顯示被模式匹配到的字符串,而非整行
		-q			靜默模式,不輸出任何信息
		-E			支持擴展的正則表達式(egrep)
		-F			支持快速匹配(fgrep)
		-A #		After,顯示被模式匹配到的後面的#行
		-B #		Before,顯示被模式匹配到的前面的#行
		-C #		Context,顯示被模式匹配到的前#行與後#行
		-P			使用perl風格的正則表達式

	PATTERN
		模式,即用於匹配的條件,將在下面介紹

2. 基本正則表達式(BRE)

Globbing回顧

通配符 意義
* 任意長度的任意字符
? 任意單個字符
[] 指定範圍內的任意單個字符
[^] 指定範圍外的任意單個字符

BRE元字符

正則表達式的介紹主要內容爲介紹其元字符,分爲以下幾類:

  • 字符匹配
  • 次數匹配
  • 位置錨定
  • 分組

字符匹配

元字符 意義
. 匹配任意字符
[] 匹配指定範圍內的字符
[^] 匹配指定範圍外的字符

注意,這裏只是確定匹配什麼字符,匹配次數並不由此限制。

關於範圍,可使用如下方式表示:

範圍 意義
[0-9],[[:digit:] 數字
[a-z],[[:lower:]] 小寫字母
[A-Z],[[:upper:]] 大寫字母
[[:punct:]] 標點符號
[[:space:]] 空白符號
[[:alpha:]] 所有字母(大寫與小寫)
[[:alnum:]] 字母與數字

以上兩個中括號的意義爲,外層標識正則表達式的範圍,內層與其中的內容共同標識一個集合,若要匹配外圍以外的,組在兩個中括號之間加上^即可,如:

[^[:lower:]]:非小寫字母

匹配次數

用在要指定其出現的次數的字符的後面,用於限定其前面字符出現的次數

元字符 意義
* 匹配其前面字符任意次(0次,1次,或多次)
\? 0次或1次
\+ 1次或多次
\{m\} m次
\{m,n\} 至少m次,至多n次

這裏需要使用轉義,因爲BRE將+、?、{、}等字符默認是作爲字字面意義進行匹配的,這裏需要使其作爲元字符使用。

另外,關於次數匹配也有以下用法:

次數表示 意義
.* 任意長度的任意字符
\{0,n\} 至多n次
\{m,\} 至少m次
貪婪模式

試想若有如下內容的文本:

one two one three one

使用以下命令進行匹配:

grep -o "one.*one" test.grep

得到的結果爲:

one two one three one

而事實上“one two one”也是滿足模式的,這裏之所以是如此結果,是因爲grep默認工作在 貪婪模式 下,這意味着grep會儘可能長地匹配字符。

若要儘可能短地匹配,則需要其在非貪婪模式下匹配,而grep與egrep默認是不支持這種模式的。

我們可以使用-P選項,以爲使用Perl語言風格的正則表達式進行模式匹配,號稱Perl的正則表達式引擎是非常強大的。

Perl風格中,在次數限定元字符後加 ? 可使其工作在非貪婪模式下,如:

grep -o -P "one.*?one" test.grep

結果爲

one two one

位置錨定

元字符 意義
^ 錨定行首
$ 錨定行尾
\<或\b 錨定詞首,用於單詞左側
\>或\b 錨定詞尾,用於單詞右側

常見用法

模式 意義
\<PATTERN\> 匹配完整單詞
^PATTERN$ 用PATTERN匹配整行
^$ 空白行
^[[:space:]]*$ 空行或包含空白字符的行

分組與引用

有時需要將一個組合作爲一個單位進行限定,如要匹配出現多個連續的“ab”,此時可使用分組

分組是使用小括號實現的,不過在BRE中需要轉義,如以上要求的模式應寫爲\(ab\)*

分組的另一個作用爲,可再次引用匹配到的內容(後向引用),如若使用r..t匹配到了“root”,則在下次引用時,引用的佔位符將被替換爲“root”。

分組括號中的模式匹配到的內容會被正則表達式引擎記錄於內部變量中,這些變量的命名方式爲\1,\2,\3,……

如,有以下文本內容:

He likes his lover.
She loves her liker.
He loves his lover.
She likes her liker.

grep '\(l..e\).*\1r'將會匹配到:

He loves his lover.
She likes her liker.

  • 顯示/proc/meminfo文件中以不區分大小的s開頭的行;
    grep -i '^s' /proc/meminfo
    grep '^[sS]' /proc/meminfo
    
  • 顯示/etc/passwd中以nologin結尾的行;
    grep 'nologin$' /etc/passwd
    
  • 取出默認shell爲/sbin/nologin的用戶列表
    grep "nologin$' /etc/passwd | cut -d: -f1
    
  • 取出默認shell爲bash,且其用戶ID號最小的用戶的用戶名
    grep 'bash$' /etc/passwd | sort -n -t: -k3 | head -1 | cut -d: -f1
    
  • 顯示/etc/inittab中以#開頭,且後面跟一個或多個空白字符,而後又跟了任意非空白字符的行;
    grep "^#[[:space:]]\{1,\}[^[:space:]]" /etc/inittab
    
  • 顯示/etc/inittab中包含了:一個數字:(即兩個冒號中間一個數字)的行;
    grep ':[0-9]:' /etc/inittab
    
  • 顯示/boot/grub/grub.conf文件中以一個或多個空白字符開頭的行;
    grep '^[[:space:]]\{1,\}' /boot/grub/grub.conf
    
  • 顯示/etc/inittab文件中以一個數字開頭並以一個與開頭數字相同的數字結尾的行;
    grep '^\([0-9]\).*\1$' /etc/inittab
    
  • 找出"netstat -tan"命令的結果中以’LISTEN’後跟0、1或多個空白字符結尾的行;
    netstat -tan | grep "LISTEN[[:space:]]*$"
    

3. 擴展正則表達式(ERE)

ERE與BRE類似,只是將更多的字符納入了元字符,如此在使用時將不必轉義,其他與BRE類似,與這裏做如下總結

字符匹配

元字符 意義
. 匹配任意字符
[] 匹配指定範圍內的字符
[^] 匹配指定範圍外的字符

匹配次數

元字符 意義
* 匹配其前面字符任意次(0次,1次,或多次)
? 0次或1次
+ 1次或多次
{m} m次
{m,n} 至少m次,至多n次

位置錨定

元字符 意義
^ 錨定行首
$ 錨定行尾
\<或\b 錨定詞首,用於單詞左側
\>或\b 錨定詞尾,用於單詞右側

分組與引用

元字符 意義
() 分組
\1, \2, \3, … 後向引用

或者

元字符 意義
| 表示“或者”之意

該元字符在BRE中並未出現,這裏需要說明的是,|匹配的是真個左邊或整個右邊,而不是單個字符,如:
c|Cat可以匹配的是c與Cat,而非cat與Cat,若要用C|cat表示C|c可以使用()分組:(C|c)at

四、文本處理命令

wc

wc以爲Word Count,用於文本統計,用法如下:

wc [OPTION]... [FILE]...
	[OPTION]
		-l		print the newline counts
		-L		print the length of the longest line
		-w		print the word counts
		-c		print the byte counts
		-m		print the character counts

該命令隻影響輸出,不修改源文件

cut

cut顧名思義,可用於文本分割,用法爲:

cut OPTION... [FILE]...
	OPTION
		-d			指定字段分隔符,選項與分隔符之間可以沒有空格,默認分隔符是空格
		-f#			指定要顯示的字段,後跟數字,可以沒有空格,例:
			-f1			顯示第一個
			-f1,3		顯示第一個和三個
			-f1-3		顯示第一個到第三個
		
		--output-delimiter=STRING
			指定輸出時的分隔符,默認與輸入時的相同

該命令隻影響輸出,不修改源文件

sort

sort以爲排序,用法爲:

sort [OPTION]... [FILE]...
	[OPTION]
		-n				按照數值(的大小)排序
		-r, --reverse	逆序
		-t				指定分隔符
		-k				以哪個字段爲關鍵字進行排序
		-u				排序後相同的行只顯示一次
		-f				排序時忽略字符大小寫

該命令隻影響輸出,不修改源文件

uniq

該命令用於報告或移除重複的行,用法爲:

uniq [OPTION]... [INPUT [OUTPUT]]
	 [OPTION]
		-c:顯示每行的重複次數
		-u:僅顯示未曾重複過的行
		-d:僅顯示重複過的的行

需要說明的是,只有內容相同且位置相鄰,才被文人是相同的行

diff

diff意爲difference,用於逐行對比文件的不同,用法爲:

diff [OPTION]... FILES
	[OPTION]
		-u:使用unified機制,即顯示要修改的上下文,默認爲3行

可以使用輸出重定向,將生成的補丁文件保存:

diff /PATH/TO/OLDFILE /PATH/TO/NEWFILE > /PATH/TO/PATCH_FILE

patch

patch意爲補丁,是用於向原始文件打補丁的工具,用法爲:

patch [OPTIONS] -i /PATH/TO/PATCH_FILE /PATH/TO/OLDFILE
patch /PATH/TO/OLDFILE < /PATH/TO/PATCH_FILE

五、文件查找

locate

locate意爲位置,該命令將基於已經建立的文件索引進行搜索,速度較快,但是非實時,使用方式爲:

locate [OPTION]... PATTERN...
	[OPTION]
		-b:只匹配基名
		-c:統計出共有多少個符合條件的文件
		-r:基於BRE搜索

另外,可以使用updatedb命令來手動生成文件索引數據庫,注意,該操作將會遍歷整個根文件系統,對資源佔用較大

find

與locate不同的是,find命令是實時查找,支持多種搜索方式,但是速度較慢,用法爲:

find [PATH] [CONDITION] [ACTION]
	[PATH]		搜索路徑,默認爲當前目錄
	
	[CONDITION]	搜索條件,可以是文件名、大小、類型、權限等標準,默認爲指定路徑下的所有文件,即無條件
		-name 'FILENAME'	對文件名做精確匹配,區分大小寫
			文件名通配
				*			任意長度的任意字符
				?			任意單個字符
				[]			指定範圍內的
				[^]			指定範圍外的

		-iname 'FILENAME'	文件名匹配不區分大小寫
		-regex 'PATTERN'	基於正則表達式進行文件名匹配
			以PATTERN匹配整個文件路徑字符串,而不僅僅是文件名

		-user USERNAME		根據屬主查找
		-group GRPNAME		根據屬組查找

		-uid UID			根據UID查找
		-gid GID			根據GID查找
			若一個文件的屬主用戶被刪除,則該文件的屬主將變爲刪除用戶的UID,此時,該文件沒有屬主,屬組亦然

		-nouser				查找沒有屬主的文件
		-nogroup			查找沒有屬組的文件

		-type TYPE			根據文件類型查找
			f		普通文件
			d		目錄
			c		字符設備文件
			b		塊設備文件
			l		符號鏈接文件
			p		命名管道
			s		套接字文件
		
		-size [+|-]
			指定查找大小,後跟數字和單位,若沒給出單位,則爲默認的“字節”,+和-表示至少、至多,可使用其他單位,如
				#k
				#M
				#G

			指定大小查找時,若沒有指定+或-,會匹配在給定大小爲1單位一內的所有文件
				即:
					#:(#-1, #]
					-#: [0, #-1]
					+#: (#, ∞)

		根據文件的時間戳查找
			以天爲單位(time)
				-mtime[+|-]#			修改時間/天
				-ctime [+|-]#			改變時間/天
				-atime [+|-]#			訪問時間/天
				
			以分鐘爲單位(min)		
				-mmin [+|-]#			修改時間/分鐘
				-cmin [+|-]#			改變時間/分鐘
				-amin [+|-]#			訪問時間/分鐘
	
			+#:[#+1, ∞)
			-#:[0, #)
			#:[#, #+1)

		根據文件的權限查找
			-permMODE:精確匹配
			/MODE: 任何一類用戶(u,g,o)的任何一位(r,w,x)權限匹配
				9位權限位
				常用於查找某類用戶的特定權限是否存在
				
				只判斷一位權限時,+和-一樣
			-MODE: 每一類用戶都必須同時擁有爲其制定的權限標準

			例:文件權限644
				-perm 644	查找文件權限爲644的文件,可以匹配
				-perm /222	查找有用戶有寫權限的文件,可以匹配
				-perm /002	查找其他用戶有寫權限的文件,不能匹配
				-perm -444	可以匹配

		組合條件
			-a			與(and)
			-o			或(or)
			-not,!		非(NOT)
			
			若給出了多個查找條件而沒有指定邏輯鏈接方式,默認爲與(-a)

	[ACTION]		對符合條件的文件做什麼操作,默認爲輸出至屏幕
		-print		輸出至標準輸出,默認操作
		-ls			類似ls -l 的形式顯示
		-delete		刪除查找到的文件
		
		-fls /path/to/somefile
			查找到的文件的長格式信息保存至指定文件中
			
		-exec COMMAND {} \;
			find把查找到的所有文件一次性地傳遞給-exec執行
			執行命令,有些命令不接受過多參數,此時命令執行可能會失敗,此時使用以下方式:
			find | xargs COMMAND
			{}是文件名佔位符,用於引用查找到的文件名自身
			注意:\;前必須有空格,\;二者之間不能都空格
			
		-ok COMMAND {} \;		交互式-exec

六、vim

1. 介紹

同nano一樣,vim也是一款全屏幕的編輯器,他是vi(visual Interface)編輯器的進化版(improved),功能異常強大。

vim是一個模式化的編輯器,這裏介紹常用幾種模式

  • 編輯模式:默認處於該模式下,在該模式中,鍵盤操作通常被解釋爲編輯命令而非輸入字符
  • 輸入模式:該模式下鍵盤的輸入將被錄入到屏幕
  • 末行模式:即命令行模式,可在此進行復雜的操作
  • 可視化模式:便於快捷查看、選定等

其界面如下:
vim界面

2. 常用參數

vim [OPTIONS] /PATH/TO/SOMEFILE...
	OPTIONS
		-o			水平分割顯示
		-O			垂直分割顯示
			Ctrl+w,箭頭	窗口間跳轉
			若打開單個文件,這裏將不會分隔窗口
		
		+N				打開文件並定位在第N行的行首
		+/PATTERN		打開文件後,直接讓光標處於第一個被PATTERN匹配到的行的行首
		+				打開文件並定位在最後一行

3. 模式間轉換

編輯模式–>輸入模式
i:insert,在當前光標所在字符的前面,轉換爲輸入模式
a:append,在當前光標所在字符的後面,轉換爲輸入模式
o:在當前光標所在行的下方,新建一行,並轉爲輸入模式
I:在當前光標所在行的行首,轉換爲輸入模式
A:在當前光標所在行的行尾,轉換爲輸入模式
O:在當前光標所在行的上方,新建一行,並轉換爲輸入模式
輸入模式–>編輯模式
ESC鍵
編輯模式–>末行模式
:
末行模式–>編輯模式
ESC
命令行有內容時可敲擊多次ESC
編輯模式–>可視化模式
v

4. 常用通配符

通配符 意義
. 當前行
$ 最後一行
$-1 倒數第二行
+# 向下的#行

5. 編輯模式

移動光標

逐字符移動

按鍵 動作
h或← 向左
l或→ 向右
j或↓ 向下
k或↑ 向上
#COMMAND:可以移動#個字符如:
4l:向右移動4字符
6←:向左移動6字符

以單詞爲單位移動

按鍵 動作
w 移至下一個單詞的詞首
b 調至當前或前一個單詞詞首
e 跳至當前或下一個單詞詞尾

#COMMAND:可以移動#個單詞

行內跳轉

按鍵 動作
0 數字0,跳至絕對行首
^ 跳至行首的第一個非空白字符
$ 跳至絕對行尾

行間跳轉

按鍵 動作
#G 跳轉至第#行
G 跳轉至最後一行
1G或gg 跳轉至第一行

句子間跳轉

按鍵 動作
) 下一句
( 上一句

段落間跳轉

按鍵 動作
} 下一段
{ 上一段

翻屏

按鍵 動作
Ctrl+f 向文件尾部翻一屏
Ctrl+b 向文件首部翻一屏
Ctrl+d 向文件尾部翻半屏
Ctrl+u 向文件首部翻半屏
Enter 按行向後翻

刪除單個字符

按鍵 動作
x 刪除光標所在處的單個字符
#x 刪除光標所在處及向後的共#個字符

刪除命令:d

d命令跟跳轉命令組合使用,用於刪除光標當前位置到跳轉到位置的字符,#d跳轉符:如:

按鍵 動作
3dw 刪除光標向後的3個單詞
d^ 刪除至行首
d$ 刪除至行尾
dd 刪除當前光標所在行
#dd 刪除包括當前光標所在行在內的下#行

修改命令:c

即先刪除內容,再轉換爲輸入模式,用法同d命令,如

按鍵 動作
c$ 刪除光標值行尾內容並轉爲輸入模式
c^ 刪除光標值行首內容並轉爲輸入模式
cc 刪除光標所在行內容並轉爲輸入模式
#cc 刪除包括當前光標所在行在內的下#行並轉爲輸入模式

複製命令:y

使用方法同刪除命令,如

按鍵 動作
c$ 複製光標值行尾內容
c^ 複製光標值行首內容
cc 複製光標所在行內容
#cc 複製包括當前光標所在行在內的下#行

粘貼命令:p

vim中編輯的內容可以撤銷,最後一次刪除的內容會被保存至內存的緩衝區中,可以用於下次粘貼至他處,相當於剪切

p(小寫)
如果刪除或複製的內容爲整行內容,則粘貼至光標所在行的下方;
如果刪除或複製的內容爲非整行,則粘貼至光標所在字符的後面;
P(大寫)
如果刪除或複製的內容爲整行內容,則粘貼至光標所在行的上方;
如果刪除或複製的內容爲非整行,則粘貼至光標所在字符的前面

替換命令:r

先按r,再按下字符,可以將當前光標所在的字符替換的鍵入的字符

#r:向後替換#個字符

可敲R進入替換模式,替換模式下鍵入的字符將直接替換原字符

撤銷

按鍵 動作
u 撤銷前一次的編輯操作
#u 撤消指定次數的操作
U 僅撤銷光標所在行的編輯操作
Ctrl+r 還原撤銷

連續u命令可撤消此前的n次編輯操作,默認最多撤銷50次操作

重複之前的操作

在編輯模式中,使用.可重複之前的操作

分屏顯示

按鍵 動作
Ctrl+w, s 水平拆分窗口
Ctrl+w, v 垂直拆分窗口

在窗口鍵切換的方式爲:Ctrl+w,箭頭

關閉文件

ZZ (大寫)保存並退出

6. 可視化模式

該模式可以選中光標劃過的所有字符

按鍵 動作
v 按字符選取
V 按行選取

經常結合編輯命令:d,c,y

7. 末行模式

打開文件

按鍵 動作
:e FILE 打開新文件
:r FILE 讀取其他文件至當前文件

關閉文件

按鍵 動作
:q 不保存退出(若修改了文件內容則無法退出)
:wq 保存並退出
:x 同: wq ,保存並退出
:q! 強行不保存退出
:w 保存(只讀屬性的文件無法保存)
:w /PATH/TO/SOMEFILE 另存爲
:w! 強行保存(管理員)
qall 退出所有文件
wall 保存所有文件

移動光標

直接給出行號,回車即可

地址定界

使用地址定界的形式爲:START,END,如

定界操作 意義
# 第#行
m,n 第m行到第n行
m,+n 相對定界,從第m行開始,往後n行
. 當前行
$ 最後一行
$-2 倒數第3行
/PAT1/,/PAT2/ 自光標處開始匹配,從第一次能夠被模式一(PAT1)匹配到的行開始,到以第一次能夠被模式二(PAT2)匹配到的行結束,中間的所有行,通常的使用形式爲/PAT/,$
% 全文,相當於1,$

編輯操作

末行模式中的編輯操作格式爲:地址定界後跟一個編輯命令,可實現對範圍內的內容進行相應的編輯操作。如:

指令 操作
#d 刪除光標所在行與向下的行供#行
%y 複製全部內容
m,nw /PATH/TO/SOMEWHERE 將m行到n行的內容寫入指定文件中
m,nr /PATH/FROM/SOMEFILE 將m至n行的內容替換爲指定文件中的內容

查找

指令 操作
/PATTERN 從當前光標向尾部查找
?PATTERN 從當前光標向首部查找
n 與命令同方向
N 與命令反方向

查找並替換:s

在末行模式下使用s命令,用法同sed中的s命令4

s命令默認只替換每行中第一次被模式匹配到的字符串,其使用格式爲:

:地址定界s/查找模式/替換爲的內容/修飾符
分隔符
/爲分隔符,可以換成其他字符,如s### s@@@ …
緊跟在s之後的字符,會被解析成定界符
若pattern中或string中有與分隔符相同的,使用\轉義
查找模式
這裏的模式支持正則表達式
替換爲的內容
替換爲的內容不支持正則表達式,但可以使用\1, \2, … 等後向引用,還可以使用&引用前面查找時查找到的整個內容
修飾符
修飾符 意義
g global,全局替換,替換(一行中)所有被模式匹配到的字符串,默認只替換每一行的第一個
i ignore-case,忽略字符大小寫

如:

  • 刪除全文的行首的#
    :%s@^#@@g

  • 將1到30行行首是非#的行加上#
    :1,30s@^[^#]@#&@g

  • 將行首的空白字符替換爲空
    :%s/^[[:space:]]\+//

  • 將每行開頭爲空白符的行首加一個#
    :%s/^[[:space:]]/#&/

分屏顯示

按鍵 動作
:sp [FILE] 水平分割顯示
:vsp [FILE] 垂直分割顯示

文件間切換

當使用vim同時打開多個文件而沒有指定分屏時,默認是將第一個文件全屏顯示的,此時可以通過如下方式在打開的文件之間切換:

指令 操作
: next 切換至下一個文件
: previous 切換至前一個文件
: last 切換至最後一個文件
: first 切換至第一個文件

與shell交互

即在vim中執行shell命令,在末行模式下輸入!,後跟命令即可。

若在vim中編輯了內容,在未保存的情況下意外關閉,在下次編輯時vim將會警告,可以使用vim -r 恢復未保存的數據,刪除同目錄下的*.swp文件,亦可在警告窗口中根據提示進行操作

8. 定製vim的工作特性

在末行模式下使用set可設定相關參數,用於修改vim的當前配置,不帶任何參數的set命令可查看set的幫助

顯示或取消顯示行號

: set number			顯示行號
: set nu

: set nonumber			取消顯示
: set nonu

設定忽略或區分字符大小寫

: set ignorecase			忽略大小寫
: set ic

: set noic					區分大小寫

設定自動縮進

: set autoindent		自動縮進
: set ai

: set autoindent		取消縮進
: set noai

高亮搜索

: sethlsearch			高亮顯示搜索到的文本
: set nohlsearch		取消高亮顯示搜索到的文本
: nohl					取消高亮顯示搜索到的文本

語法高亮

: syntax on		開啓語法着色
: syntax off		關閉語法着色

高亮顯示與之匹配的括號

:setshowmatch		顯示與之匹配的括號
:set sm			

:setshowmatch		取消顯示
:set nosm

該操作可立即生效,作用域僅爲當前vim進程

9. vim的配置文件

vim有兩種配置文件

  • /etc/vimrc:對所有用戶生效
  • ~/.vimrc:僅對當前用戶生效,若不存在,可自行創建

通過將以上屬性設置指令寫入配置文件,可永久生效

10. 獲取幫助

vim是一個很複雜的工具,這裏介紹的只是基礎用法,關於幫助的獲取,可使用如下方式:

  • : help:在末行模式下輸入help和查看vim的幫助
  • : help SUBJECT:help後跟一個關鍵字可查看該部分幫助

另外,vimtutor命令中有關於vim的相關教程

七、特殊權限

1. 概念

記得之前在介紹umask時,其內容有4位,最高位就是特殊權限爲的遮罩碼。

Linux的特殊權限有三種,分別爲

  • SUID
  • SGID
  • Sticky

詳細介紹之前, 先來回顧下安全上下文的概念。

安全上下文
  1. 任何一個可執行程序文件能不能啓動爲進程,取決發起者對程序文件是否擁有執行權限;
  1. 啓動爲進程之後,其進程的屬主爲發起者;進程的屬組爲發起者所屬的組;
權限匹配模型:
(1) 判斷進程的屬主,是否爲被訪問的文件的屬主,若是,則應用屬主權限,否則
(2) 判斷進程的數組,是否屬於進程的數組,若是,則應用屬組權限,否則
(3) 應用其他權限

執行的進程是當前shell的子進程,shell以當前用戶身份運行

SUID

  • 意義:運行某程序時,相應進程的屬主是程序文件自身的屬主,而不是啓動者
  • 表現位置:表現爲文件屬主執行權限位上的s或S,如果FILE本身原來就有執行權限(x),則SUID顯示爲s,否則顯示S
  • 設置SUID權限
    chmod u+s FILE …
    chmod u-s FILE …
    

SGID

  • 意義:具有SGID的目錄,用戶在目錄下創建時文件或目錄時,其屬組不再是用戶自己的基本組,而是這個目錄的屬組,僅對目錄有意義
  • 表現位置:表現爲文件(一般是目錄)屬組執行權限位上的s或S,如果FILE本身原來就有執行權限(x),則SGID顯示爲s,否則顯示S
  • 設定SGID權限
    chmod g+s DIR …
    chmod g-s DIR …
    

Sticky

  • 意義:對於公共可寫的目錄,用戶可以創建文件,可以刪除自己的文件,但無法刪除別的用戶的文件,僅對目錄有意義
  • 表現位置:表現爲文件(一般是目錄)其他用戶執行位上的t或T,如果FILE本身原來就有執行權限(x),則Sticky顯示爲t,否則顯示T
  • 設定Sticky權限
    chmod o+t DIR …
    chmod o-t DIR …
    

特殊權限位

SUID SGID Sticky 八進制
0 0 0 0
0 0 1 1
0 1 0 2
0 1 1 3
1 0 0 4
1 0 1 5
1 1 0 6
1 1 1 7

如此可使用chmod MMMM FILE的方式對文件進行權限管理,如

chmod 5755 /tmp/test.mod

意爲將/tmp/test.mod文件的權限設定爲SUID,Sticky,rwxr-xr-x

八、FACL

FACL(Filesystem Access Control List)文件訪問控制列表,是附加原有權限模型之上另一層權限控制機制,讓普通用戶能夠控制賦權給另外的用戶或組的賦權機制,保存至文件擴展屬性信息中,利用文件擴展屬性保存額外的訪問控制權限。

getfacl

可以使用getfacl命令來讀取FACL,如:

[root@localhost tmp]# getfacl test.facl
# file: test.facl
# owner: root
# group: root
user::rw-
user:user1:rwx
group::r--
mask::rwx
other::r--

輸出信息有文件名、屬主屬組、以及權限信息,權限信息格式如下:

user|group:[USER_NAME|GROUP_NAME]:PERM

若用戶名或組名爲空,則標識該權限設定應用於屬主或屬組

其他說明
默認(沒設置FACL時)只有文件名、屬主、屬組,以及9個權限位,設置之後會顯示特定用戶或組的權限
設置FACL時,超出mask給出的權限,但沒有設置時,mask將自動變化爲每次設置的最高權限
若文件設置了FACL,則在ls -l查看時,權限位後會多一個+,但在複製、歸檔等操作時,可能會丟失擴展屬性

setfacl

setfacl用於設定文件的FACL,用法如下:

setfacl OPTION FILE
	OPTION
			-m		設定
				u:USERNAME:PERM
				g:GRPNAME:PERM

				d:u:USERNAME:PERM
				d:g:GRPNAME:PERM
					當操作對象爲目錄時,使用d選項,使在該目錄下創建的文件自動繼承設置的擴展權限
				m::PERM
					設定mask

		-x		取消
			u:USERNAME
			u:GRPNAME

			m::PERM
				取消mask

		-b		清除所有FACL
		-R		遞歸設置,對當前目錄以及子目錄生效

  1. https://blog.csdn.net/xiyangyang410/article/details/85090293 ↩︎

  2. 讀取方式後文將做介紹 ↩︎

  3. 關於特殊變量後續會詳細介紹 ↩︎

  4. 後續將會介紹sed ↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章