<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      shell 基礎學習

      Shell工具

      以下所有工具命令不會直接改變原文件,需要用重定向到文件中才能保存

      grep

      行過濾工具:grep [選項] '關鍵字' 文件名

      -n 行號
      
      -i 忽略大小寫ignore
      
      -v 取反
      
      ^key 以...開頭
      
      key$ 以...結尾
      
      ^$ 匹配空行
      
      -A 后幾行after
      
      -B 前幾行before
      
      -C 上下文context
      
      -w 匹配單詞 ('hello' 不會匹配到'helloworld') 精確匹配
      
      -o 只打印出關鍵字本身
      
      -c 統計匹配的行數
      
      -e 使用正則
      

      cut

      列截取工具:cut 選項 文件名

      -c 以字符為單位截取
      
      -d 自定義分隔符,默認為'\t'
      
      -f 與-d一起使用,指定截取哪個區域
      
      cut -d: -f1,6,7 文件   以:分割,截取第1,6,7列
      
      cut -c1-4 文件 截取文件中每行的第1-4個字符(同理5-表示第5開始到結尾)
      

      (head tail) -1

      sort

      sort用于排序,它將文件的每一行作為一個單位,從首字符向后,依次按ASCII碼值進行比較,最后將他們升序輸出

      -u 去除重復行(不管重復行連續與否)
      -r 降序排列,默認升序
      -o 將排序結果輸出到文件中,類似重定向符號>
      -n 以數字排序,默認是按字符排序
      -t 分隔符
      -k 第N列(與-t配合類似于cut的-d -f)
      -b 忽略前導空格
      -R 隨機排序,每次運行結果不同
      

      uniq

      用于去除連續的重復行

      -i 忽略大小寫
      -c 統計重復行次數
      -d 只顯示重復行
      

      tee

      從標準輸入讀取并寫入到標準輸出和文件,即:雙向覆蓋重定向(屏幕輸出|文本輸入)

      -a 雙向追加重定向
      

      echo hello world | tee 文件

      屏幕顯示hello world 文件內容也是hello world

      diff

      用于逐行比較文件的不同

      注意:diff描述兩個文件不同的方式是告訴我們怎樣改變第一個文件之后與 第二個文件匹配

      diff [選項] 文件1 文件2

      -b 不檢查空格
      -B 不檢查空白行
      -i 不檢查大小寫
      -W 忽略所有空格
      --normal 正常格式顯示(默認)
      -c 上下文格式顯示
      -u 合并格式顯示
      
      

      正常格式顯示:c=change d=delete a=add

      上下文格式:!改變 -刪除 +增加

      合并格式:+ - 只顯示第一個文件需要增加和刪除的內容

      比較兩個目錄的不同:

      1. 默認情況下也會比較兩個目錄里相同文件的內容
      2. 如果只需要比較兩個目錄里文件的不同,不需要進一步比較文件內容,需要加-q選項
      注意touch dir/file{1..5}會在該目錄生成5個文件
      

      以一個文件為標準,修改其他文件,并且修改的地方較多時,我們可以通過打補丁的方式將文件1更新成文件2

      1. 先找出文件不同,然后輸出到一個文件 diff -uN (-N 將不存在的文件當做空文件) file1 file2 > file.patch
      2. 將不同內容打補丁到文件 patch file1 file.patch
      3. 測試驗證
      • paste

      用于合并文件行

      -d 自定義間隔符,默認是tab
      -s 串行處理,非并行
      

      tr

      用于字符轉換,替換和刪除,主要用于刪除文件中的控制字符或進行字符轉換

      用法1:命令的執行結果交給tr處理,其中string1用于查詢,string2用于轉換處理
      # commands | tr 'string1' 'string2'
      
      用法2:tr處理的內容來自文件,記住要使用"<"標準輸入
      # tr 'string1' 'string2' < filename
      
      用法3:匹配string1進行相應操作,如刪除操作
      # tr options 'string1' < filename
      

      options

      -d 刪除字符串1中所有輸入字符
      -s 刪除所有連續重復出現的字符序列,只保留第一個,即將重復出現的字符串壓縮為一個字符 aaaaabbbbb  ab
      壓縮空格有奇效
      

      常用的匹配字符串:一個對一個的替換

      a-z或[:lower:]  匹配所有小寫字母
      A-Z或[:upper:]  匹配所有大寫字母
      0-9或[:digit:]  匹配所有數字
      [:alnum:]       匹配所有字母和數字
      [:alpha:]       匹配所有字母
      [:blank:]       匹配所有水平空白
      [:punct:]       匹配所有標點符號
      [:space:]       匹配所有水平或垂直的空格
      [:cntrl:]       匹配所有控制字符  \f \n \r \t
      :set list 在vim中會顯示控制字符
      

      '' 或'[]'包住多個要替換的字符都是一樣的

      常用快捷鍵

      ^c 終止前臺運行的程序
      ^z 將前臺運行的程序掛起到后臺 stopped (命令 & 表示后臺運行)
      ^d 退出 等價exit
      ^l 清屏
      ^a |home 光標移到命令行的最前端
      ^e |end 光標移到命令行的后端
      ^u 刪除光標前所有字符
      ^k 刪除光標后所有字符
      ^r 搜索歷史命令
      

      常用通配符

      * 匹配0或多個任意字符
      ? 匹配任意單個字符
      [list] 匹配list中的任意單個字符,或一組單個字符  eg: file[1-12]表示file1和file2
      [!list] 匹配除了list中的任意單個字符
      {string1,string2,...} 匹配string1,string2或更多字符串 file{1..12}表示file1到file12
      {1..6..2}表示1到6的數間隔為2的列表
      

      bash中的引號

      雙引號""  會把引號的內容當成整體來看待,允許通過$符號引用其他變量值
      單引號''  會把引號的內容當成整體來看待,禁止引用其他變量值,shell中特殊符號都被視為普通字符
      反撇號``  反撇號和$()一樣,引號或括號里的命令會優先執行,如果存在嵌套,反撇號不能用,只能用$()
      

      sed

      -i 原地刪除  eg: sed -i "/line_number/d" file_name
      

      Shell變量

      1. shell的基本語法結構

      變量定義,條件判斷,循環語句(for, until, while),分支語句,函數和數組

      1. 基本正則表達式
      2. 文件處理三劍客:grep, sed, awk的使用
      3. 使用shell腳本完成一些較復雜的任務,如服務搭建,批量處理等

      以上為基本內容,還有很多更深更難的語法需要擴充學習

      #! /bin/env bash 指定解釋器,env bash可以找到環境變量
      標準執行方式:
      (1) chmod +x 腳本名字
      (2) 絕對/相對路徑
      非標準的:沒有可執行權限也可以執行腳本
      bash/sh/dash 腳本名字  
      +x 可以顯示執行過程 (用于調試!!!)
      +n 用于查看腳本語法問題
      source命令   # 讀取該文件,獲知其內容,使其在當前終端定義并生效
      

      變量名區分大小寫

      變量名和值不要加入特殊字符(有空格的用括號括起來)

      變量名不能以數字開頭

      等號兩邊不能有任何空格

      定義變量基本方式

      A=1234567
      echo A
      echo {A}
      echo {A:2:4} 3456 切出片段,以第3個字母為起點,長度為4 切片
      

      命令執行結果賦值給變量

      A=`hostname`
      A=$(hostname)
      

      交互式定義變量

      讓用戶自己給變量賦值,或來自文件( < filename)

      read [選項] 變量名

      -p 定義提示用戶的信息
      -n 定義字符數(限制變量值的長度)
      -s 不顯示(不顯示用戶輸入的內容)
      -t 定義超時時間,默認單位為妙(限制用戶輸入變量值的超時時間)
      

      declare 定義有類型的變量

      給變量做一些限制,固定變量的類型,比如:整型、只讀

      用法:declare 選項 變量名=變量值

      -i 將變量看成整數 declare -i A=123
      -r 定義只讀變量   declare -r B=hello
      -a 定義普通數組;查看普通數組
      -A 定義關聯數組;查看關聯數組
      -x 將變量通過環境導出  declare -x AAA=123456 等于 export AAA=123456
      

      unset 取消變量

      變量的分類

      本地變量:當前用戶自定義的變量,當前進程中有效,其他進程及當前進程的子進程無效。

      環境變量:當前進程有效,并且能被子進程調用

      • env查看當前用戶的環境變量
      • set查詢當前用戶的所有變量(臨時變量與環境變量)
      • export 變量名=變量值 或者 變量名=變量值; export 變量名

      全局變量:全局所有的用戶和程序都能調用,且繼承,新建的用戶也默認能調用

      $HOME/.bashrc 當前用戶的bash信息,用戶登錄時讀取 定義別名、umask、函數等
      $HOME/.bash_profile 當前用戶的環境變量,用戶登錄時讀取
      $HOME/.bash_logout 當前用戶退出當前shell時最后讀取 定義用戶退出時執行的程序等
      $etc/bashrc 全局的bash信息,所有用戶都生效
      $etc/profile 全局環境變量信息 系統和所有用戶都生效
      

      以上文件修改后,都需要重新source讓其生效或者退出重新登錄

      用戶登錄系統讀取相關文件的順序:

      1. /etc/profile
      2. $HOME/.bash_profile
      3. $HOME/.bashrc
      4. $etc/.bashrc
      5. $HOME/.bash_logout
      

      一般全局與局部沖突,以局部為主,如果在讀取全局profile前設置局部變量,則局部變量被全局覆蓋

      系統變量(內置bash中的變量):shell本身已經固定好了它的名字和作用

      $? 上一條命令執行后返回的狀態,狀態值為0表示執行正常,非0表示執行異常或錯誤
      $0 當前執行的程序或腳本名
      $# 腳本后面接的參數的個數
      $* 腳本后面所有參數,參數當成一個整體輸出,每一個變量參數之間以空格隔開
      $@ 腳本后面所有參數,參數是獨立的,也是全部輸出
      $1-$9 腳本后面的位置參數,$1表示第1個位置參數,依次類推
      $(10)-$(n) 擴展位置參數,第10個位置變量必須用{}大括號括起來(2位數字以上括起來)
      $$ 當前所在進程的進程號,如echo $$
      $! 后臺運行的最后一個進程號(當前終端)
      !$ 調用最后一條命令歷史中的參數
      

      jobs 查看后臺進程

      kill -9 %數字  # 終止這個后臺進程(數字為job number)
      

      簡單四則運算

      $(())  echo $((1+1))
      $[]    echo $[10-5]
      expr   expr 10 / 5   # 要有空格且*要轉義  不能求**冪
      let    n=1;let n+=1 等價于 let n=n+1  # 省略$
      

      當要求小數運算時 只能有bc eg:echo 1+1.5|bc 或 bc模型輸入

      條件判斷語法

      • 格式1:test 條件表達式
      • 格式2:[ 條件表達式 ]
      • 格式3:[[ 條件表達式 ]] 支持正則

      更多的判斷,man test去查看,很多的參數都用來進行條件判斷

      (一)判斷文件類型

      -e 判斷文件是否存在(任何類型文件)
      -f 判斷文件是否存在并且是一個普通文件
      -d 判斷文件是否存在并且是一個目錄
      -L 判斷文件是否存在并且是一個軟連接文件
      -b 判斷文件是否存在并且是一個塊設備文件
      -S 判斷文件是否存在并且是一個套接字文件
      -c 判斷文件是否存在并且是一個字符設備文件
      -p 判斷文件是否存在并且是一個命名管道文件
      

      (二)判斷文件權限

      -r 當前用戶對其是否可讀
      -w 當前用戶對其是否可寫
      -x 當前用戶對其是否可執行
      -u 是否有suid,高級權限冒險位
      -g 是否sgid,高級權限強制位
      -k 是否有t位,高級權限粘滯位
      -s 判斷文件是否存在并且不為空 
      ! -s 判斷文件是否存在并且為空
      

      (三)判斷文件新舊

      這里的新舊是指文件的修改時間

      file1 -nt file2 比較file1是否比file2新
      file1 -ot file2 比較file1是否比file2舊
      file1 -ef file2 比較是否為同一個文件,或者用于判斷硬鏈接,是否指向同一個inode
      

      (四)判斷整數

      -eq 相等 如:if [ "$a" -eq "$b" ]
      -ne 不等
      -gt 大于
      -lt 小于
      -ge 大于等于
      -le 小于等于
      <   小于(需要雙括號),如:(("$a" < "$b"))
      <=  小于等于(需要雙括號),如:(("$a" <= "$b"))
      >   大于(需要雙括號),如:(("$a" > "$b"))
      >=  大于等于(需要雙括號),如:(("$a" >= "$b"))
      

      (五)判斷字符串

      -z 判斷是否為空字符串,字符串長度為0則成立
      -n 判斷是否為非空字符串,字符串長度不為0則成立
      string1 = string2 判斷字符串是否相等
      string != string2 判斷字符串是否不等
      

      字符串最好用""括起來,形成一個整體

      (六)多重條件判斷

      -a 和 &&   邏輯與   [ 1 -eq 1 -a 1 -ne 0 ] [ 1 -eq 1 ] && [ 1 -ne 0 ]
      -o 和 ||   邏輯或   [ 1 -eq 1 -o 1 -ne 1 ] [ 1 -eq 1 ] || [ 1 -ne 1 ]
      

      && 前面的表達式為真,才會執行后面的代碼

      || 前面的表達式為假,才會執行后面的代碼

      ; 只用于分割命令或表達式,不考慮前面的語句是否正確執行,都會執行;號后面的內容

      多個條件在一起時要從左往右依次按&&和||的方式判斷


      類c風格的數值比較

      在(( ))中,=表示賦值,==表示判斷,!=表示不等于,<
      

      字符串比較

      注意:雙引號引起來,看作一個整體;= 和 == 在 [ 字符串 ] 比較中都表示判斷(用于字符串的判斷)
      

      [ ] 和 [[ ]]的區別

      當字符串為空時,[[ ]]可以不將字符串用雙引號括起來且不報錯,[]不行 eg [ $A = hell ]
      && 寫在 [[ ]]之間不會報錯
      

      流程控制語句

      if [ condition ];then
      			command
      	elif [ condition2 ];then
      			command
      	else
      			command
      fi
      
      [ 條件 ] && command
      

      上圖選擇的路很多,能走的只有一條

      pgrep命令:以名稱為依據從運行進程隊列中查找進程,并顯示查找到的進程id
      選項:
      -o 僅顯示找到的最小(起始)進程號 
      -n 僅顯示找到的最大(結束)進程號
      -l 顯示進程名稱
      -p 指定父進程號;pgrep -p 4764 查看父進程下的子進程id
      -g 指定進程組
      -t 指定開啟進程的終端
      -u 指定進程的有效用戶id
      

      &>/dev/null 可以停止將輸出顯示到屏幕上

      先執行,再用$?判斷是否執行成功

      ps 和 pgrep 可以用來判斷一個進程是否存在

      wget , curl 和 elinks --dump 用于判斷一個服務是否可以正常訪問

      循環控制語句

      for循環

      固定次數的循環

      (一)列表循環

      for variable in {list}
      		do
      				command
      				command
      		done
      		
      或者
      for variable in a b c
      		do
      				command
      				command
      		done
      

      可以用{1..10}或sep或枚舉 進行循環

      (二)不帶列表循環

      由用戶指定參數和參數的個數

      for variable         # 實際是 for i in '"$@"'
      		do
      				command
      				command
      		done
      

      (三)類C風格的for循環

      for ((expr1;expr2;expr3))
      	do
      			command
      			command
      	done
      for ((i=1;i<=5;i++))
      	do
      			echo $i
      	done
      

      continue 跳出當前循環

      break 跳出循環

      exit 跳出程序

      練習:

      1. 如果目錄不存在就新建
      test -d /tmp/dir1 && mkdir /tmp/dir1 -p
      或者
      if [ ! -d /tmp/dir1 ];then mkdir /tmp/dir1 -p fi
      

      邏輯運算符與條件語句,這兩者是等價的可以相互轉換

      1. 判斷所輸整數是否為質數
      #!/bin/env bash
      
      read -p "請輸入一個正整數數字:" number
      
      [ $number -eq 1 ] && echo "$number不是質數" && exit
      [ $number -eq 2 ] && echo "$number是質數" && exit
      
      for i in `seq 2 $[$number-1]`
      	do 
      			[ $[$number%$i] -eq 0 ] echo "$number不是質數" && exit
      	done
      echo "$number是質數" && exit
      
      1. 批量創建用戶

      批量添加5個新用戶,以u1到u5命名,并統一加一個新組,組名為class,統一改密碼為123

      #!/bin/env bash
      
      grep -w ^class /etc/group &>/dev/null  # 精確判斷是否存在class這個組
      test $? -ne 0 && groupadd class
      
      for ((i=1;i<=5;i++))
      do
      		useradd -G class u$i
      		echo 123|passwd --stdin u$i
      done
      

      批量創建5個用戶stu1-stu5,要求這幾個用戶的家目錄都在/rhome

      #!/bin/bash
      
      #判斷rhome是否存在
      [ -f /rhome ] && mv /rhome /rhome.bak
      test ! -d /rhome && mkdir /rhome
      
      for ((i=1;i<=5;i++))
      do
      		useradd -d /rhome/stu$i stu$i
      		echo 123|password --stdin stu$i
      done
      
      1. 局域網內腳本檢查主機網絡通訊

      局域網內,把能ping通的IP和不能ping通的IP分類,并保存到兩個文本文件中

      10.1.1.1 - 10.1.1.10

      #!/bin/bash
      ip=10.1.1
      for ((i=1;i<=10;i++))
      do
      		ping -c1 $ip.$i &>/dev/null
      		if [ $? -eq 0 ];then
      			echo "$ip.$i is ok" >> /tmp/ip_up.txt # >>是追加
      		else
      			echo "$ip.$i is down" >> /tmp/ip_down.txt # >>是追加
      done
      

      time ./path/demo.sh #可以用來記錄執行時間

      并發執行以上任務

      #!/bin/bash
      ip=10.1.1
      for ((i=1;i<=10;i++))
      do
      { # (1) 花括號包起來
      		ping -c1 $ip.$i &>/dev/null
      		if [ $? -eq 0 ];then
      			echo "$ip.$i is ok" >> /tmp/ip_up.txt # >>是追加
      		else
      			echo "$ip.$i is down" >> /tmp/ip_down.txt # >>是追加
      }& #(2) 在后臺執行
      done
      wait #(3) 等待所有線程執行完畢
      echo "IP is ok"
      

      while循環

      while 表達式
      	do 
      		 command
      	done
      

      死循環

      while true
      while :  #等價
      

      tail -f 循環讀取文件尾部,動態顯示更新的內容

      while read ip passwd
      do
      		command
      done < ip.txt # 用循環從文件中讀取
      

      until語法結構

      條件為假就進入循環,條件為真就退出循環

      until expression [ 1 -eq 1 ] (( 1 >= 1 ))
      		do
      				command
      				command
      		done
      

      新建10個user,其中后5個的home目錄在rhome下

      #!/bin/env bash
      
      if [ -d /rhome ];then
      	echo "/rhome目錄已存在"
      else
      	mkdir /rhome
      	echo "/rhome目錄不存在,已完成創建"
      fi
      
      i=1
      until [ $i gt 10 ]
      do
      		if [ $i -le 5 ];then
      				useradd -u $[1000+$i] stu$i
      				echo 123|passwd --stdin stu$i
      		else 
      				useradd -d /rhome/stu$i stu$i
      				echo 123|passwd --stdin stu$i
      		fi
      		let i++
      done
      
      

      隨機數

      系統變量:RANDOM,默認會產生0~32767的隨機整數

      前言:要想調用變量,不管是什么變量,都要用$

      #產生0~100之間的隨機數
      echo $[ $RONDOM%101 ]
      
      #產生10~99之間的隨機數
      echo $[ $RONDOM%90+10 ] 0~89 + 10
      
      head -隨機產生的行號 file_name|tail -1
      

      嵌套循環

      for while until 都可以相互嵌套
      

      echo默認有換行的屬性,-n 取消換行

      shift位移

      shift 使位置參數向左移動,默認移動一位,可以使用shift 2
      
      eg: ./demo.sh 1 2 3 4   
      for i
      do
      	echo $1 # 依次輸出 1 2 3 4
      shift
      done
      

      expect

      expect自動應答 tcl語言

      需求1:A遠程登錄到server上什么都不做

      #!/usr/bin/expect
      #開啟一個程序
      set ip 10.1.1.1 # 定義變量   [ lindex $argv 0 ] 可以從腳本的參數中讀取
      set pass 123456
      spawn ssh root@$ip  # 執行程序
      捕獲相關內容
      expect {
      				"(yes/no)?" { send "yes\r";exp_continue } # exp_continue 的作用是當匹配不到yes/no時繼續
      				"password:" { send "$pass\r" } # 一定要回車才能繼續往下走 \r 或 \n 都可以
      }
      interact # 不加會退出ssh登錄
      
      expect "#"    # 期待匹配到登錄的遠端服務器終端出現#開頭
      send "rm -rf /tmp/*\r"
      send "touch /tmp/file{1..3}\r"
      send "date\r"
      send "exit\r"
      expect eof
      
      1. 循環 useradd username
      2. 登錄遠程主機->ssh->從ip.txt文件讀取IP和密碼分別賦值給兩個變量
      3. 使用expect程序解決交互問題
      #!/bin/bash
      while read ip pass
      do
      		/usr/bin/expect <<-END &>/dev/null  # 聲明一個結束符(什么都行),其中-表示后面的END不用頂格可以添加制表符
      		spawn ssh root@ip
      		expect {
      				"(yes/no)?" { send "yes\r";exp_continue } 
      				"password:" { send "$pass\r" } 
      		}
      		expect "#" { send "useradd yy1;rm -rf /tmp/*;exit\r" }
      		expect eof
      		END # 退出expect
      done < ip.txt
      

      案例分析

      1. 跳板機上的yunwei用戶生成鑰對
        • 判斷賬號是否存在(id yunwei)
        • 判斷該用戶是否有密鑰對文件 [ -f xxx ]
      2. 判斷expect是否安裝
      3. su - yunwei
      4. 判斷局域網內的主機是否ping通(循環判斷|for while until)
        • 循環判斷 for while
        • 循環體do ... done ping 主機 如果ping通,調用expect程序自動應答推送公鑰
      5. 測試驗證是否免密登錄成功
      • 功能1:管理員root創建yunwei用戶和安裝expect軟件包
      #!/bin/env bash
      # 實現批量推送公鑰
      # 判斷jumper上的yunwei賬號是否存在
      {
      	id yunwei &>/dev/null
      	[ $? -ne 0 ] && useradd yunwei && echo 123|passwd --stdin yunwei
      } &>/dev/null
      
      # 判斷expect程序是否安裝
      rpm -q expect
      [ $? -ne 0 ] && yum -y install expect && echo "expect軟件已經安裝成功"
      
      • 功能2:判斷主機是否ping通且yunwei用戶推送公鑰
      #!/bin/env bash
      # 判斷yunwei用戶密鑰對是否存在
      home_dir=/home/yunwei
      [ ! -f $home_dir/.ssh/id_rsa.pub ] && ssh-keygen -P '' -f $home_dir/.ssh/id_rsa &>/dev/null
      
      #循環檢查主機的網絡并且進行公鑰推送
      ip_txt=/path_to_txt/ip.txt
      #	文件中很多行,每一列用:分隔
      
      # tr ':' ' ' < $ip_txt|while read ip passwd
      # do
      # {
      # }&
      # done
      for i in `cat $ip_txt`  # 一行一行讀取
      do
      		ip=`echo $i|cut -d: -f1`
      		pass=`echo $i|cut -d: -f2`
      		ping -c1 $ip &>/dev/null
      		if [ $? -eq 0 ];then
      		 	echo $ip >> ~/ip_up.txt
      			/usr/bin/expect <<-END &>/dev/null
      			spawn ssh-copy-id root@$ip
      			expect "(yes/no)" { send "yes\n";exp_continue }
            expect "password:" { send "$pass\n" }
      			expect eof
      			END
      		else
      			echo $ip >> $home_dir/ip_down.txt
      		fi
      done
      
      # 測試驗證
      remote_ip=`head -1 ~/ip_up.txt`
      ssh root@$remote_ip hostname
      [ $? -eq 0 ] && echo "公鑰推送成功"
      

      sudo

      yunwei用戶sudo授權:
      visudo
      ## Allow root to run any commands anywhere
      root	ALL=(ALL)	ALL
      yunwei	ALL=(root)	NOPASSWD:ALL,!/sbin/shutdown,!/sbin/init,!/bin/rm -rf /
      
      解釋說明:
      1)第一個字段yunwei指定的是用戶:可以是用戶名,也可以是別名。每個用戶設置一行,多個用戶設置多行,也可以將
      多個用戶設置成一個別名后再進行設置
      2)第二個字段ALL指定的是用戶所在的主機:可以是ip,也可以是主機名,表示該sudo設置只在該主機上生效,
      ALL表示所有主機上都生效。!限制的都是本機,也就是限制使用這個文件的主機;一般都是指定為ALL表示所有主機,
      不管文件拷貝到那里都可以用。比如:10.1.1.1=...則表示只在當前主機生效。
      3)第三個字段(root)括號里指定的也是用戶,指定以什么用戶身份執行sudo,即使用sudo后可以享有所有root
      賬號下的權限,如果要排除個別用戶,可以在括號內設置,比如ALL=(ALL,!oracle,!pos)。
      4)第四個字段ALL指定的是執行的命令:即使用sudo后可以執行所有的命令,除了關機和刪除跟內容以外;也可以設置別名。NOPASSWD:ALL表示使用sudo的不需要輸入密碼。
      5)也可以授權給一個用戶組
      	%admin ALL=(ALL) ALL 表示admin組里的所有成員可以在任何主機上以任何用戶身份執行任何命令
      

      數組

      數組分類:

      • 普通數組:只能使用整數作為數組索引(元素的下標)
      • 關聯數組:可以使用字符串作為數組索引(元素的下標)

      普通數組

      定義:

      • 一次賦予一個值
      數組名[索引下標]=值
      array[0]=v1
      array[1]=v2
      
      • 一次賦予多個值
      數組名=(值1 值2 值3 ...)
      array=(var1 var2 var3 var4)
      
      array1=(`cat /etc/passwd`) # 將文件中每一行賦值給array1數組
      array2=(`ls /root`)
      array3=(harry amy jack "Miss Hou")
      array4=(1 2 3 4 "hello world" [10]=linux)
      

      數組的讀取

      ${數組名[元素下標]}
      
      echo ${array[0]}  # 獲取數組里第一個元素
      echo ${array[*]}  # 獲取數組里的所有元素
      echo ${#array[*]} # 獲取數組里所有元素的個數
      echo ${!array[@]} # 獲取所有數組元素的索引下標
      echo ${array[@]:1:2} # 訪問指定的元素;1代表從下標為1的元素開始獲取;2代表獲取后面幾個元素
      
      # 查看普通數組信息
      declare -a # 不僅可以定義,也可以查看當前已經定義好的數組
      

      關聯數組

      聲明關聯數組

      declare -A asso_array1
      declare -A asso_array2
      declare -A asso_array3
      

      數組賦值:

      • 一次賦一個值
      數組名[索引or下標]=變量值
      asso_array1[linux]=one
      asso_array1[java]=two
      asso_array1[php]=three
      
      • 一次賦多個值
      asso_array2=([name1]=harry [name2]=jack [name3]=amy [name4]="Miss Hou")
      
      • 查看關聯數組
      #declare -A
      declare -A asso_array1='([php]="three" [java]="two" [linux]="one")'
      declare -A asso_array2='([name3]="amy" [name2]="jack" [name1]="harry" [name4]="Miss Hou")'
      關聯數組下標無序
      關聯數組的讀取方法同普通數組
      
      • 取出一個目錄下的目錄和文件:dirname和basename
      # A=/root/Desktop/shell/mem.txt
      # echo $A
      /root/Desktop/shell/mem.txt
      # dirname $A  取出目錄
      /root/Desktop/shell
      # basename $A 取出文件
      mem.txt
      
      • 變量內容的刪除和替換
      一個"%"代表從右往左去掉一個/key/
      兩個"%%"代表從右往左最大去掉/key/
      一個"#"代表從左往右去掉一個/key/
      兩個"##"代表從左往右最大去掉/key/
      
      eg:
      # url=www.taobao.com
      # echo ${#url}   獲取變量的長度
      # echo ${url#*.}
      # echo ${url##*.}
      # echo ${url%.*}
      # echo ${url%%.*}
      

      任務:統計網站的連接次數

      #!/bin/env bash
      #count_http_80_state
      #統計每個狀態的個數
      
      declare -A array1
      states=`ss -ant|grep 80|cut -d' ' -f1` #類似netstat,但LISTEN ESTAB的狀態值顯示在開頭
      
      for i in $states
      do
      		let array1[$i]++
      done
      
      #通過遍歷數組里的索引和元素打印出來
      for j in ${!array1[@]}
      do
      		echo $j:${array1[$j]}
      done
      

      case語句

      1. case語句為多重匹配語句
      2. 如果匹配成功,執行相匹配的命令
      • 語法結構
      說明:pattern表示需要匹配的模式
      
      case var in      # 定義變量;var代表是變量名
      pattern1)			   # 模式1;用|分割多個模式,相當于or
      			command1   # 需要執行的語句
      			;;				 # 兩個分號代表命令結束
      pattern2)
      			command2
      			;;
      pattern3)
      			command3
      			;;
      			 *)		     # default, 不滿足以上模式,默認執行*)下面的語句
      			command4
      			;;
      esac						 # esac表示case語句結束
      

      案例:菜單提示讓用戶選擇需要做的事

      需求:模擬一個多任務界面,當執行程序時先顯示總菜單,然后進行選擇后做相應維護監控操作

      #!/bin/env bash
      cat <<-EOF
      		h	顯示命令幫助
      		f	顯示磁盤分區
      		d	顯示磁盤掛載
      		m	查看內存使用
      		u	查看系統負載
      		q	退出程序
      		EOF
      
      while true
      do
      	read -p "請選擇需要操作的內容(help h):" action
      	clear   # 清屏
      	cat <<-EOF
      					h	顯示命令幫助
      					f	顯示磁盤分區
      					d	顯示磁盤掛載
      					m	查看內存使用
      					u	查看系統負載
      					q	退出程序
      				EOF
      	case $action in
      			h|help)
      				cat <<-EOF
      					h	顯示命令幫助
      					f	顯示磁盤分區
      					d	顯示磁盤掛載
      					m	查看內存使用
      					u	查看系統負載
      					q	退出程序
      				EOF
      				;;
      				f)
      				lsblk
      				;;
      				d)
      				df -h
      				;;
      				m)
      				free -m
      				;;
      				u)
      				uptime
      				;;
      				q)
      				exit
      				;;
      esac
      done
      

      函數

      shell中允許將一組命令集合或語句形成一段可用代碼,這些代碼塊稱為shell函數

      給這段代碼起個名字稱為函數名,后續可以直接調用該段代碼的功能

      • 定義函數:
      函數名()
      {
      	函數體(一堆命令的集合,來實現某個功能)
      }
      
      function 函數名()
      {
      	函數體(一堆命令的集合,來實現某個功能)
      }
      
      • 函數中return說明:
      1. return可以結束一個函數,類似于循環控制語句break(結束當前循環,執行循環體后面的代碼)
      2. return默認返回函數中最后一個命令的狀態值,也可以給定參數值,范圍是0-256之間
      3. 如果沒有return命令,函數將返回最后一個指令的退出狀態值
      • 調用函數

      1)當前命令行調用,只在當前終端有效,使用前需要source該腳本

      #!/bin/bash
      hello(){
      	echo "hello lilei $1" 
      	hostname
      }
      

      2)定義到用戶的環境變量中,~/.bashrc(全局所有用戶是/etc/bashrc)

      自登錄時生效,修改后需要source
      

      3)腳本中調用

      #!/bin/bash
      menu(){
      cat <<-EOF
      					h	顯示命令幫助
      					f	顯示磁盤分區
      					d	顯示磁盤掛載
      					m	查看內存使用
      					u	查看系統負載
      					q	退出程序
      				EOF
      }
      
      menu # 調用menu
      source /path_to_file/filename.sh # 接下來可以調用其他文件的函數
      

      案例:交互輸入用戶的姓名、性別、年齡

      #!/bin/bash
      # 該函數實現用戶如果不輸入內容則一直循環直到用戶輸入為止,并且將用戶輸入的內容打印出來
      input_fun()
      {
      	input_var=""
      	output_var=$1
      	while [ -z $input_vat ]
      	do
      		read -p "$output_var" input_var
      	done
      	echo $input_var
      }
      name=`input_fun 請輸入你的姓名`
      

      遞歸寫法

      #!/bin/bash
      func()
      {
      	read -p "$1" name
      	if [ -z $name ];then
      		func $1
      	else
      		echo $name
      	fi
      }
      
      #!/bin/bash
      # jumper-server
      # 定義菜單打印功能的函數
      menu(){
      cat <<-EOF
      歡迎使用Jumper-server, 請選擇你要操作的主機:
      1. DB1-Master
      2. DB2-Master
      3. Web1
      4. Web2
      h. help
      q. exit
      	EOF
      }
      
      # 調用函數來打印菜單
      menu
      # 循環等待用戶選擇
      while true
      do
      # 菜單選擇,case...esac語句
      read -p "請選擇你要訪問的主機:" host
      case $host in
      		1)
      		ssh root@10.1.1.1
      		;;
      		2)
      		ssh root@10.1.1.2
      		;;
      		3)
      		ssh root@10.1.1.3
      		;;
      		h)
      		clear;menu
      		;;
      		q)
      		exit
      		;;
      esac
      done
      
      #將腳本放到yunwei用戶家目錄里的.bashrc里執行:
      bash ~/jumper-server.sh
      exit
      

      進一步完善:

      增強跳板機的安全性,工作人員通過跳板機訪問生產環境,但是不能在跳板機上停留

      #!/bin/bash
      # 公鑰推送成功(免密)
      trap '' 1 2 3 19 # 屏蔽ctrl-C的信號
      #打印菜單用戶選擇
      menu(){
      cat <<-EOF
      
      }
      
      # 回顧信號
      1) SIGUP     # 重新加載配置
      2) SIGINT    # 鍵盤終端^C 
      3) SIGQUIT   # 鍵盤退出 
      9) SIGKILL   # 強制終止
      15) SIGTERM  # 終止(正常結束),缺省信號
      18) SIGCONT  # 繼續
      19) SIGSTOP  # 停止
      20) SIGTSTP  # 暫停^Z
      

      正則表達式

      (Regular Expression、regex或regexp,縮寫為RE)是一種字符模式,用于在查找過程中匹配指定的字符

      許多程序語言都支持利用正則表達式進行字符串操作

      正則表達式這個概念最初是由Unix中的工具軟件(例如sed和grep)普及開的

      支持正則表達式的程序如:locate | find | vim | grep | sed |awk

      正則能干什么?

      1. 匹配郵箱、匹配身份證號碼、手機號、銀行卡號等
      2. 匹配某些特定字符串,做特定處理等等

      正則當中名詞解釋

      • 元字符

      正則表達式中具有特殊意義的專用字符,如:點(.) 星(*) 問號(?)等 和通配符中的星號和問號是不一樣的

      • 前導字符

      位于元字符前面的字符, abd* aooo.

      第一類正則表達式

      正則中普通常用的元字符

      .  匹配除了換行符以外的任意單個字符
      *  前導字符出現0次或連續多次
      .* 任意長度的字符  ab.*
      ^  行首(以...開頭)  ^root
      $  行尾(以...結尾)  bash$
      ^$  空行
      []  匹配括號里任意單個字符或一組單個字符  [abc]
      [^]  匹配不包含括號里任一單個字符或一組單個字符  [^abd]
      ^[]  匹配以括號里任意單個字符或一組單個字符開頭  ^[abc]
      ^[^] 匹配不以括號里任意單個字符或一組單個字符開頭  ^[^abc]
      
      # 正則中的其他元字符
      \<  取單詞的頭
      \>  取單詞的尾
      \< \>  單詞精確匹配      等價于 grep -w
      \{n\}  匹配前導字符連續出現n次
      \{n,\} 匹配前導字符至少出現n次
      \{n,m\} 匹配前導字符出現n次與m次之間
      \{ \}   保存被匹配的字符    
              # vim中:%s/\{10.1.1\}.1/\1.254/g  將前{}起來的用標簽\1表示 10.1.1.1 -> 10.1.1.254
      \d     匹配數字(grep -P)     [0-9]
      \w     匹配字母數字下劃線(grep -P)   [a-zA-Z0-9_]
      \s     匹配空格、制表符、換頁符(grep -P)   [\t\r\n]
      

      擴展類正則常用元字符

      grep你要用我,必須加-E或者讓你兄弟egrep來找我

      sed你要用我,必須加-r

      +		匹配一個或多個前導字符		bo+匹配boo bo
      ?		匹配零個或一個前導字符		bo?匹配b bo
      |		或										匹配a或b
      ()	組字符(看成整體)			(my|your)self: 表示匹配myself或匹配yourself
      {n}	前導字符重復n次
      {n,}	前導字符重復至少n次
      {n,m}	前導字符重復n到m次
      

      第二類正則表達式

      [:alnum:]		字母與數字字符		[[:alnum:]]+
      [:alpha:]		字母字符(包括大小寫字母)		[[:alpha:]]{4}
      [:blank:]		空格與制表符		[[:blank:]]*
      [:digit:]		數字		[[:digit:]]?
      [:lower:]		小寫字母		[[:lower:]]{4,}
      [:upper:]		大寫字母		[[:upper:]]+
      [:punct:]		標點符號		[[:punct:]]
      [:space:]		包括換行符,回車等在內的所有空白		[[:space:]]+
      

      正則表達式總結

      1. 我要找什么?
        • 找數字 [0-9] \d
        • 找字母 [a-zA-Z]
        • 找標點符號 [[:punct:]]
      2. 我要如何找?看心情找
        • 以什么為首 ^key
        • 以什么結尾 key$
        • 包含什么不包含什么 [abc] [1] [^abc] [abc]
      3. 我要找多少呀?
        • 找前導字符出現0次或連續多次 ab*
        • 找任意單個(一次)字符 ab.
        • 找任意字符 ab.*
        • 找前導字符連續出現幾次 {n}
        • 找前導字符出現1次或多次 go+

      去掉空行:

      1.查找不以大寫字母開頭的行(三種寫法)
      grep '^[^A-Z]' 2.txt
      grep -v '^[A-Z]' 2.txt
      grep '^[^[:upper:]]' 2.txt
      2.查找有數字的行(兩種寫法)
      grep '[0-9]' 2.txt
      grep -P '\d' 2.txt
      3. 查找一個數字和一個字母連起來的
      grep -E '[0-9][a-zA-Z]|[a-zA-Z][0-9]' 2.txt
      4. 查找不以r開頭的行
      grep '^[^r]' 2.txt
      5. 查找以點結束的
      grep '\.$' 2.txt
      6. 去掉空行
      grep -v '^$' 2.txt
      grep '^[^$]' 2.txt   # 錯誤寫法,[]中的只表示單個字符
      7. 查找完全匹配abc的行
      grep '\<abc\>' 2.txt
      8. 查找A后有三個數字的行
      grep -E 'A[0-9]{3}' 2.txt
      grep 'A[0-9]\{3\}' 2.txt
      9. 統計root在/etc/passwd里出現了幾次
      grep -o 'root' 1.txt|wc -l
      10. 用正則表達式找出自己的IP地址、廣播地址、子網掩碼
      ifconfig eth0|grep Bcast|grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\'
      ifconfig eth0|grep Bcast|grep -E -o '([0-9]{1,3}.){3}[0-9]{1,3}'
      ifconfig eth0|grep Bcast|grep -P -o '\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}' # -P后不用添加-E
      ifconfig eth0|grep Bcast|grep -P -o '(\d{1,3}.){3}\d{1,3}'
      ifconfig eth0|grep Bcast|grep -P -o '(\d+.){3}\d+'
      也可以使用egrep 配合 [:digit:]
      11. 找出文件中的ip地址并且打印替換成172.16.2.254
      grep -o -E '([0-9]{1,3}.){3}[0-9]{1,3}' 1.txt|sed -n 's/192.168.0.\(254\)/172.16.2.\1/p'
      12. 找出文件中的ip地址
      grep -o -E '([0-9]{1,3}\.){3}[0-9]{1,3}' 1.txt
      13. 找出全部是數字的行
      grep -E '^[0-9]+$' test
      14.找出郵箱地址
      grep -E '^[0-9]+@[a-z0-9]+\.[a-z]+$'
      

      1. abc ??

      posted @ 2021-04-01 23:36  demianzhang  閱讀(114)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产在线精品福利91香蕉| 1000部精品久久久久久久久 | av午夜福利一片免费看久久| 国产一区二区日韩在线| 久久月本道色综合久久| 亚洲午夜精品国产电影在线观看| 狠狠色噜噜狠狠狠狠7777米奇 | ww污污污网站在线看com| 国产jlzzjlzz视频免费看| 又黄又爽又色的少妇毛片| 伊人色综合久久天天小片| 六安市| 亚洲精品综合久久国产二区| 国产情侣激情在线对白| 国产精品久久久久影院| 日韩成人午夜精品久久高潮| 国产精品一区二区中文| 国产网红女主播精品视频| 国产粉嫩区一区二区三区| 国产精品欧美福利久久| 强行交换配乱婬bd| 狠狠噜天天噜日日噜无码| 一区二区中文字幕久久| 66亚洲一卡2卡新区成片发布| 国产视频一区二区三区麻豆| 日本一区二区三区免费播放视频站| 久久精品无码av| 亚欧洲乱码视频一二三区| 手机看片日本在线观看视频| 本溪市| 国产亚洲欧洲AⅤ综合一区| 久久精品国产亚洲AV瑜伽| 国产精品一区中文字幕| 国产婷婷精品av在线| 日韩AV高清在线看片| 国产精品天干天干综合网| 思思久99久女女精品| 亚洲AV日韩AV高清在线观看| 国产精品自在拍首页视频8| 国产av亚洲一区二区| 天天躁日日躁狠狠躁中文字幕|