《Shell腳本學(xué)習(xí)指南》學(xué)習(xí)筆記

這是我學(xué)習(xí)linux以及shell的時(shí)候選擇的一本書(shū),是O'REILLY圖書(shū)系列的《Shell腳本學(xué)習(xí)指南》,看完之后,對(duì)最基本的Linux命令行操作,文本處理,進(jìn)程管理都會(huì)有一個(gè)全方面的認(rèn)識(shí)。

第一章:背景知識(shí)

  • POSIX

POSIX,Portable Operating System Interface。
是UNIX系統(tǒng)的一個(gè)設(shè)計(jì)標(biāo)準(zhǔn),很多類UNIX系統(tǒng)也在支持兼容這個(gè)標(biāo)準(zhǔn),如Linux。
遵循這個(gè)標(biāo)準(zhǔn)的好處是軟件可以跨平臺(tái)。所以windows也支持就很容易理解了,那么多優(yōu)秀的開(kāi)源軟件,支持了這個(gè)這些軟件就可能有windows版本,就可以完善豐富windows下的軟件。

第二章:入門(mén)

#!

  cat > nursers
  #! /bin/bash -
  
  who | wc -l

之后每條命令都會(huì)用bash運(yùn)行
所以,如果是py文件可以在第一行加上#! /bin/python, 這樣就可以使用./來(lái)運(yùn)行它

grep命令

-v 反向選取,輸出選不滿足條件的

printf命令

  • 用法與C語(yǔ)言非常接近

tr命令

tr命令可以對(duì)來(lái)自標(biāo)準(zhǔn)輸入的字符進(jìn)行替換、壓縮和刪除

  -c或——complerment:取代所有不屬于第一字符集的字符;
  -d或——delete:刪除所有屬于第一字符集的字符;
  -s或--squeeze-repeats:把連續(xù)重復(fù)的字符以單獨(dú)一個(gè)字符表示;
  -t或--truncate-set1:先刪除第一字符集較第二字符集多出的字符
  
  echo aa.,a 1 b#$bb 2 c*/cc 3 ddd 4 | tr -cd '0-9 \n' 
  1 2 3 4
  
  tr 'A-Z' 'a-z'

重定向與管道

<\ 改變標(biāo)準(zhǔn)輸入

tr命令
translate charactors

  tr -d '0-9'

可以將標(biāo)準(zhǔn)輸入中的數(shù)字全都刪除

  tr -d '0-9' < mytext.txt

這就改變了標(biāo)準(zhǔn)輸入而是將txt文件中的內(nèi)容進(jìn)行修改

>\ 改變標(biāo)準(zhǔn)輸出

>>\ 輸出到文件時(shí)不覆蓋文件而是附加

|\ 建立管道

  program1 | program2

將program1的標(biāo)準(zhǔn)輸出修改為program2的標(biāo)準(zhǔn)輸入

  tr -d '\r' < mytext.txt | sort > mytext2.txt

過(guò)程:

  1. tr的標(biāo)準(zhǔn)輸入改成mytext.txt
  2. tr的標(biāo)準(zhǔn)輸出變?yōu)閟ort的標(biāo)準(zhǔn)輸入
  3. sort的標(biāo)準(zhǔn)輸出重定向到mytext2.txt

/dev/null和/dev/tty

/dev/null是一個(gè)垃圾桶,所有輸出到這里的數(shù)據(jù)都會(huì)被扔掉

    echo 12321 > /dev/null

/dev/tty將重定向一個(gè)終端,鍵盤(pán)輸入maybe,所以這個(gè)是用來(lái)作為輸入的

  read password < /dev/tty

將會(huì)強(qiáng)制從/dev/tty中讀取數(shù)據(jù),一般情況下不寫(xiě)問(wèn)題也不大貌似

stty -echo
可以將輸入不顯示在屏幕上
stty echo
重新顯示

Shell腳本的參數(shù)

$1代表第一個(gè)參數(shù)
$2代表第二個(gè)參數(shù)

  cat > finduser
  #! /bin/sh
  
  who | grep $1
  ^D

使用的時(shí)候就可以./finduser lxc

簡(jiǎn)單的執(zhí)行跟蹤

set -x可以設(shè)置是否跟蹤命令,跟蹤命令是指每條命令執(zhí)行時(shí)候在前面價(jià)一個(gè) + 并顯示出來(lái)
一般寫(xiě)在腳本里

.profile .bashrc區(qū)別

.profile是每次登陸時(shí)運(yùn)行
.bashrc是每次運(yùn)行bash時(shí)運(yùn)行

第三章:查找與替換

正則表達(dá)式與BRE,ERE

BRE是基本正則表達(dá)式(Basic Regular Expression)
ERE是擴(kuò)展正則表達(dá)式子(Extended Regular Expression)
BRE是grep的默認(rèn),而程序中一般使用ERE,如python神馬的,+就屬于ERE的meta符號(hào)
grep -E 表示ERE
grep 則表示BRE

一些小筆記

  • . 用來(lái)匹配任意一個(gè)字符
  • + 是之前的字符一個(gè)或多個(gè) ERE
  • * 是之前的字符0個(gè)或多個(gè)
  • 是之前的字符有或沒(méi)有 ERE
  • [abc] abc中的一個(gè)
  • [a-f0-9] 16進(jìn)制字符
  • (abc) 連續(xù)的abc,代表一個(gè)整體,后面可以以加入*+之類的 ERE
  • {a,b} 表示前面的字符出現(xiàn)a,b次,或者可以不寫(xiě)b精確a次,有逗號(hào)表示沒(méi)有上限
  • 一些字符集[:alnum:], [:alpha:]
  • [^]匹配不在指定字符組內(nèi)的任一字符

sed命令

sed用來(lái)處理文本里的每一行,可以查找,替換,刪除,顯示等等等等,其功能完全包含grep,tr等命令

  • 它的最為常用的功能就是s:
  sed 's/要匹配的字符/要替換成的字符/g' file  
  • 其中/代表分界符,可以用其他符號(hào)代替;g代表搜索全文件,不寫(xiě)則找到第一個(gè)就結(jié)束了

舉個(gè)例子:

  find /home/tolstoy -type d -print |    -type d表示類型為directory
  sed 's;/home/tolstoy/;/home/lt/;' |
  sed 's/^/mkdir /' |                    插入mkdir指令
  sh -x                                  -x表示指令追蹤

這里開(kāi)始是我后面補(bǔ)上的筆記:

  sed
  -n 取消默認(rèn)的輸出
  -e 進(jìn)行多項(xiàng)編輯,即進(jìn)行多次sed命令
  sed -e '.....' -e '.....'
  -f 指定sed腳本的文件名,就是說(shuō)sed命令可以寫(xiě)在一個(gè)腳本里的
  
  p命令,不加-n的話選中的行會(huì)輸出兩遍
  sed -n '3,5p' a.txt  # 打印第3~5行
  sed -n '3,4d' a.txt  # 刪除第3~4行
  d命令
  sed '/My/,/You/d' a.txt #刪除包含"My"的行到包含"You"的行之間的行
  sed '/My/,10d' a.txt #刪除包含"My"的行到第十行的內(nèi)容
  s命令
  sed -n '1,20s/My$/You/gp' datafile
  1~20行中,文末的My替換為You并輸出

cut命令

cut 命令從文件的每一行剪切字節(jié)、字符和字段并將這些字節(jié)、字符和字段寫(xiě)至標(biāo)準(zhǔn)輸出。
如果不指定 File 參數(shù),cut 命令將讀取標(biāo)準(zhǔn)輸入。必須指定 -b、-c 或 -f 標(biāo)志之一。

  cut
  -b :以字節(jié)為單位進(jìn)行分割。這些字節(jié)位置將忽略多字節(jié)字符邊界,除非也指定了 -n 標(biāo)志。  
  -c :以字符為單位進(jìn)行分割。  
  -d :自定義分隔符,默認(rèn)為制表符。  
  -f :與-d一起使用,指定顯示哪個(gè)區(qū)域。   
  -n :取消分割多字節(jié)字符。僅和 -b 標(biāo)志一起使用。如果字符的最后一個(gè)字節(jié)落在由 -b 標(biāo)志的 List 參數(shù)指示的<br />范圍之內(nèi),該字符將被寫(xiě)出;否則,該字符將被排除。  

舉2個(gè)例子:

  cut -d : -f 1,5 /etc/passwd     該命令以:分割,取每行的第1,5列
  ls -l | cut -c 1-10             該命令取第1~10個(gè)字符,正好是文件的讀寫(xiě)執(zhí)行權(quán)限

join命令

將兩個(gè)文件中,指定欄位內(nèi)容相同的行連接起來(lái)。

awk命令

awk是一種“單命令行程序”
它的使用模式為:

  awk 'program' [ file ]

和sed命令很像
其中program的基本格式為 pattern { action }

舉個(gè)例子:

  awk -F : '{print $1, $5 }' /etc/passwd    以:作為分隔符,輸出第一字段第五字段

第四章:文本處理工具

sort命令

-r 反轉(zhuǎn) -n 以數(shù)值排序,比如10就要排在2的后面 -k 選擇按第幾個(gè)字段排序,當(dāng)有多個(gè)-k的時(shí)候就優(yōu)先左邊再右邊 -k 1.2,2.3 從第一個(gè)字段的第二個(gè)字符比較到第二個(gè)字段的第三個(gè)字符 -t 選擇字段的分隔符,默認(rèn)以空白分隔 -f 忽略大小寫(xiě) -u 去重
舉幾個(gè)例子:

  sort -t: -k4n -k3n /etc/passwd 以:作為分隔符,先按照第四字段數(shù)值排序再按第三字段數(shù)值排序

uniq命令

sort中的-u選項(xiàng)雖然會(huì)刪除重復(fù),但是它知識(shí)按照鍵值進(jìn)行排序而不是按照整行內(nèi)容,因此我們需要uniq命令

uniq -c 在輸出上加上計(jì)數(shù)

舉個(gè)例子:

  sort a.txt | uniq

fmt命令

常常用在管道中,用來(lái)重新格式化段落,嘴饞工的功能就是規(guī)定輸出寬度

  cat a.txt | fmt -w 50

wc命令

輸出行數(shù),字?jǐn)?shù),字節(jié)數(shù)

  cat a.txt | wc
  輸出: 18 155 960
  -c 字節(jié)數(shù)
  -l 行數(shù)
  -w 字?jǐn)?shù)

head命令, tail命令

  head -n8 顯示前八行
  tail -n9 顯示后九行
  tail -f -n2 監(jiān)視最后兩行,這時(shí)tail命令永遠(yuǎn)不會(huì)結(jié)束

file命令

file將參數(shù)文件內(nèi)容的前幾個(gè)字節(jié)與樣式數(shù)據(jù)庫(kù)進(jìn)行比對(duì),再輸出一份簡(jiǎn)短報(bào)告

  file a.txt
  輸出: a.txt: ASCII text

第五章:管道的神奇魔力

umask命令

  umask 077  這條命令使得之后創(chuàng)建的文件只有當(dāng)前用戶有讀寫(xiě)權(quán)限

默認(rèn)情況下的umask值是022(可以用umask命令查看),此時(shí)你建立的文件默認(rèn)權(quán)限是644(6-0,6-2,6-2),
建立的目錄的默認(rèn)權(quán)限是755(7-0,7-2,7-2),可以用ls -l驗(yàn)證一下哦 現(xiàn)在應(yīng)該知道umask的用途了吧,
它是為了控制默認(rèn)權(quán)限,不要使默認(rèn)的文件和目錄具有全權(quán)而設(shè)的

文件用6減,目錄用7減

chmod命令

  chmod 755 file  數(shù)字命名法
  chmod a+x file  文字設(shè)定法
<權(quán)限范圍>+<權(quán)限設(shè)置> 使權(quán)限范圍內(nèi)的目錄或者文件具有指定的權(quán)限
<權(quán)限范圍>-<權(quán)限設(shè)置> 刪除權(quán)限范圍的目錄或者文件的指定權(quán)限
<權(quán)限范圍>=<權(quán)限設(shè)置> 設(shè)置權(quán)限范圍內(nèi)的目錄或者文件的權(quán)限為指定的值

權(quán)限范圍:
u :目錄或者文件的當(dāng)前的用戶
g :目錄或者文件的當(dāng)前的群組
o :除了目錄或者文件的當(dāng)前用戶或群組之外的用戶或者群組
a :所有的用戶及群組,默認(rèn)

權(quán)限代號(hào):
r :讀權(quán)限,用數(shù)字4表示
w :寫(xiě)權(quán)限,用數(shù)字2表示
x :執(zhí)行權(quán)限,用數(shù)字1表示
- :刪除權(quán)限,用數(shù)字0表示
s :特殊權(quán)限 

本章內(nèi)容

本章講了很多腳本的實(shí)例,可以把它寫(xiě)到腳本里,一般用法就是

script < infile > outfile

第六章:變量、判斷、重復(fù)動(dòng)作

export, readonly, env, unset命令

  LXC=zhu    普通變量,注意不要加空格
  export LXC
  export LXC=zhu
  export -p
  export命令是把變量放到環(huán)境里,可供應(yīng)所有執(zhí)行中的程序使用,-p是顯示所有環(huán)境變量
  unset LXC    unset命令會(huì)刪除變量
  readonly LXC=zhu     創(chuàng)建只讀變量
  readonly -p
  env LXC=dazhu command 這樣會(huì)在command中使用新的LXC變量,但是shell中原來(lái)的LXC不變

$:變量展開(kāi)

  $LXC    最普通的
  ${LXC}   復(fù)雜腳本中最好這樣寫(xiě)
  ${LXC:-word} 存在則返回LXC,否則返回word
  ${LXC:=word} 存在則返回LXC,否則返回word且把LXC賦值為word
  ....類似的還有不少

$1, $2, ... ${10}位置參數(shù)

有一些特殊變量表示特殊的參數(shù), $表示把它們顯示出來(lái):
$#, $*, $@.......

這些都是用在腳本里的

shell腳本中的內(nèi)置變量

  #     目前進(jìn)程的參數(shù)個(gè)數(shù)
  @     傳遞給當(dāng)前進(jìn)程的命令行參數(shù)
  *     當(dāng)前進(jìn)程的命令行參數(shù)
  ?     前一命令的推出狀態(tài)
  $     shell程序的進(jìn)程編號(hào)
  0     shell程序的名稱
  HOME  根目錄
  PPID  父進(jìn)程編號(hào)

算術(shù)運(yùn)算

算數(shù)運(yùn)算與C語(yǔ)言幾乎一模一樣,但是一定要放在$((...))

  $((2 + 3))
  $((3 && 4)) #1

退出狀態(tài)

每條shell命令都有一個(gè)退出狀態(tài)
0表示進(jìn)程成功,其他數(shù)字都是失敗
可以用$?來(lái)查看上一條命令的退出狀態(tài)

if-elif-else-fi

shell的if語(yǔ)句比較特殊它接受一個(gè)命令,如果執(zhí)行成功則相當(dāng)于if判斷成功

  if grep pattern myfile > /dev/null
  then
    ...    grep成功
  else
    ...    grep失敗
  fi

! && ||可以被用于腳本中
有一點(diǎn)比較特殊,a && b, a失敗了就不會(huì)執(zhí)行b,a || b,a成功了不會(huì)執(zhí)行b

$1, $2, ... ${10}位置參數(shù)

有一些特殊變量表示特殊的參數(shù), $表示把它們顯示出來(lái):
$#, $*, $@.......

這些都是用在腳本里的

shell腳本中的內(nèi)置變量

  #     目前進(jìn)程的參數(shù)個(gè)數(shù)
  @     傳遞給當(dāng)前進(jìn)程的命令行參數(shù)
  *     當(dāng)前進(jìn)程的命令行參數(shù)
  ?     前一命令的推出狀態(tài)
  $     shell程序的進(jìn)程編號(hào)
  0     shell程序的名稱
  HOME  根目錄
  PPID  父進(jìn)程編號(hào)

算術(shù)運(yùn)算

算數(shù)運(yùn)算與C語(yǔ)言幾乎一模一樣,但是一定要放在$((...))

  $((2 + 3))
  $((3 && 4)) #1

退出狀態(tài)

每條shell命令都有一個(gè)退出狀態(tài)
0表示進(jìn)程成功,其他數(shù)字都是失敗
可以用$?來(lái)查看上一條命令的退出狀態(tài)

if-elif-else-fi

shell的if語(yǔ)句比較特殊它接受一個(gè)命令,如果執(zhí)行成功則相當(dāng)于if判斷成功

  if grep pattern myfile > /dev/null
  then
    ...    grep成功
  else
    ...    grep失敗
  fi

! && ||可以被用于腳本中
有一點(diǎn)比較特殊,a && b, a失敗了就不會(huì)執(zhí)行b,a || b,a成功了不會(huì)執(zhí)行b

test命令

  test [ expression ]
  [ [ expression ] ]
  這兩種寫(xiě)法都是可以的
  
  test string   返回string是不是null
  test -b file  file是塊設(shè)備文件
  test -d file  file是目錄
  ...
  test s1 = s2  字符串s1與s2相同
  test n1 -lt n2  n1小于n2
  ...

用來(lái)返回真?zhèn)危梢杂迷谀_本的if語(yǔ)句中

  一般腳本里會(huì)這樣寫(xiě)
  if [ "X$1" = "X-f" ]    X防止字符串是空的
  then
    ...

case語(yǔ)句

語(yǔ)法有點(diǎn)特殊,用到再查吧

后面有用到

for循環(huán)

  第一種:
  for i in atl*.xml
  do
    echo $i
    mv $i $i.old
    sed '.....' < $i.old >$i
  done
  第二種
  for i     # 循環(huán)命令行參數(shù)
  do
    case $i in
    -f)   ...
          ;;
    ...
    esac
  done

while和until循環(huán)

while(until) condition
do
  statements
done

while是condition成功返回就繼續(xù)執(zhí)行,until是反之

shell也有break和continue

shift命令

shift讓所有參數(shù)順移  
原來(lái)的$1沒(méi)了, 原來(lái)的$2變成$1, ...
配合
while [ $# -gt 0 ]
do
  shift
done
可以對(duì)一個(gè)個(gè)參數(shù)進(jìn)行處理!  

getops命令

簡(jiǎn)化腳本的參數(shù)處理

  #!/bin/bash
  while getopts "a:bc" arg #選項(xiàng)后面的冒號(hào)表示該選項(xiàng)需要參數(shù),即必選
  do
          case $arg in
              a)
                  echo "a's arg:$OPTARG" #參數(shù)存在$OPTARG中
                  ;;
              b)
                  echo "b"
                  ;;
              c)
                  echo "c"
                  ;;
              ?)  #當(dāng)有不認(rèn)識(shí)的選項(xiàng)的時(shí)候arg為?
              echo "unkonw argument"
          exit 1
          ;;
          esac
  done

函數(shù)

  wait_for_user () {
    until who | grep "$1" > /dev/null
    do
      sleep ${2:-30}
    done
  }

用法
  wait_for_user phil
  wait_for_user phil 60
  • 在函數(shù)中,$1, $2變成了傳遞給函數(shù)的參數(shù)而不是腳本的參數(shù),函數(shù)之行完畢就恢復(fù)
  • 函數(shù)可以使用return來(lái)返回執(zhí)行狀態(tài),不寫(xiě)的話就默認(rèn)為 return $?
  • 函數(shù)里并沒(méi)有局部變量,和全局都是共享的

第七章:輸入輸出、文件與命令執(zhí)行

read命令

  read lxc
  read還可以一次讀入多個(gè)變量,分割符默認(rèn)空格,為$IFS的值

重定向

  腳本正文內(nèi)提供輸入數(shù)據(jù)
  << EOF
  cat << EOF
  > one
  > two
  > EOF
  one
  two

文件描述符

  0,1,2: 標(biāo)準(zhǔn)輸入,標(biāo)準(zhǔn)輸出,標(biāo)準(zhǔn)錯(cuò)誤輸出
  make > results.txt 2>&1
  上面這個(gè)命令順序很重要,反了就不對(duì)
  exec命令可以改變shell本身I/O設(shè)置
  exec 2> /tmp/file
  exec 3< /some/file
  read lxc <&3

printf

  printf "%.2f %s\n" 123.4567 abc
  123.46 abc

~波浪號(hào)展開(kāi)

  vi ~/.profile     #當(dāng)前用戶根目錄
  vi ~phil/.profile #phil用戶的根目錄
  read user
  vi ~$user/.profile

通配符

  ?       任意單個(gè)字符
  *       任何字符串
  [set]   任何在set內(nèi)的字符
  [!set]  任何不在set的字符

echo 加帶通配符的內(nèi)容,用來(lái)顯示當(dāng)前目錄下符合條件的文件名

  echo .* #顯示隱藏文件

$() 命令替換

$()里面可以加上命令,并把輸出放入其他命令中

  舉個(gè)例子,實(shí)現(xiàn)head -10 file
  count=$(echo $1 | sed 's/^-//')
  shift
  sed ${count}q "$@"

算術(shù)運(yùn)算

  i=1
  while [ "$i" -le 5 ]
  do
    echo i is $i
    i=$((i + 1))
  done

轉(zhuǎn)義

  echo \*      單個(gè)反斜杠可以轉(zhuǎn)義
  *
  echo ' $ \'  單引號(hào)內(nèi)的全部看成原來(lái)的意思
   $ \
  # 雙引號(hào)會(huì)正確處理所有meta字符
  # 所以說(shuō)單引號(hào)和雙引號(hào)功能是完全不同的

eval語(yǔ)句

eval的作用是取出參數(shù),并再執(zhí)行它們一次

  舉個(gè)例子稍微體會(huì)一下
  list page="ls | more"
  $listpage      #會(huì)報(bào)錯(cuò),找不到|
  eval $listpage #會(huì)正常執(zhí)行的

subShell與代碼塊

這些是一起執(zhí)行的代碼,區(qū)別是放在()中的是開(kāi)新進(jìn)程,放在{}中的不開(kāi)新進(jìn)程

比如在新進(jìn)程中使用cd就不會(huì)改變當(dāng)前的目錄

內(nèi)建命令

shell中命令的查找順序?yàn)椋?/p>

  1. 特殊內(nèi)建命令
  2. 腳本里的函數(shù)
  3. 一般內(nèi)建命令
  4. $PATH中的東西

alias命令

  alias lxc="ls -a"
  unalias lxc

source 與 ./執(zhí)行的區(qū)別

source是讀取文件并執(zhí)行其中的命令,不需要執(zhí)行權(quán)限!
.是source的別名

./中的.是當(dāng)前目錄的意思,是需要執(zhí)行權(quán)限的!

set命令

功能很多

  set -x 命令跟蹤
  set -o xtrace 同上
  set +o xtrace 關(guān)閉
  set有一種格式是set -o .... 打開(kāi)某個(gè)功能,set +o ...關(guān)閉某個(gè)功能

第八章:產(chǎn)生腳本

本章介紹了兩個(gè)腳本

一個(gè)是pathfind,一個(gè)是build-all

awk程序

工作模式:

awk 'pattern {action}' file

awk -f programfile inputfiles

一些例子:

  emp.data:
  Beth  4.00    0
  Dan   3.75    0
  kathy 4.00    10
  Mark  5.00    20
  Mary  5.50    22
  Susie 4.25    18
  
  1.基本用法:
  awk '$3 >0 { print $1, $2 * $3 }' emp.data
  
  2.pattern和action都可以省略
  省略pattern就匹配每一行
  省略action就print匹配的行
  
  3.內(nèi)建變量
  $0:整行, $1~$n:第某個(gè)字段
  NF:字段個(gè)數(shù), $NF最后一個(gè)字段
  NR:行號(hào)
  
  4.可以使用printf
  { printf("%-8s $%6.2f\n", $1, $2 * $3) }
  第一個(gè)規(guī)格 %-8s 將一個(gè)姓名以字符串形式在8個(gè)字符寬度的字段中左對(duì)齊輸出。第二個(gè)規(guī)格 %6.2f 將薪酬以數(shù)字的形式,保留小數(shù)點(diǎn)后兩位,在6個(gè)字符寬度的字段中輸出。

  5.多樣的pattern
  !($2 < 4 && $1 == "Susie")
  
  6.BEGIN和END
  BEGIN用于第1行前
  END用于最后一行后面
  這個(gè)可以用來(lái)使得輸出更明確
  
  7.使用變量
      { pay = pay + $2 * $3 }
  END { print NR, "employees"
        print "total pay is", pay
        print "average pay is", pay/NR
      }
  
  8.內(nèi)置函數(shù)
  length($1) 統(tǒng)計(jì)$1字符個(gè)數(shù)
  
  9.action里面還支持一些for,if,while語(yǔ)句
  
  10.還支持?jǐn)?shù)組

第十章:文件處理

ls命令

一般用到-a -l

  ls -al
  drwx------+  4 luphil  staff   136 12  7 13:02 Desktop
  第二欄代表link數(shù)量
  倒數(shù)二三四是時(shí)間,日,月 (近六個(gè)月中的最后修改時(shí)間)

stat命令

stat可以列出文件的meta信息

使用touch命令修改時(shí)間戳

  touch a
  # 若a存在則更新a的最后修改時(shí)間
  touch -t 199212210800.00 mybirthday
  # 創(chuàng)造特定時(shí)間戳

臨時(shí)文件

  • 可以放到/tmp中去

  • 為了防止臨時(shí)文件和其他用戶的文件重復(fù)了,可以使用
    touch abc.$$
    這樣子創(chuàng)建的文件名就帶上了進(jìn)程號(hào)

  mktemp 創(chuàng)建臨時(shí)文件
  mktemp lxc.XXXXXXXX 在當(dāng)前目錄創(chuàng)建臨時(shí)文件,隨機(jī)值會(huì)替換XXXX

cat /dev/random | od -x | tr -d ' ' | head -1
/dev/random和/dev/urandom可以源源不斷產(chǎn)生隨機(jī)值

尋找文件

  1. locate
    對(duì)文件名建立數(shù)據(jù)庫(kù),快速查找文件

  2. which
    找PATH下的文件

  3. type

type gcc
gcc is /usr/locl/bin/gcc
  1. find
    強(qiáng)大

find命令

  find 要尋找的目錄 選項(xiàng)
  -atime n n天前訪問(wèn)的文件
  -ctime
  -follow
  -group g 選定組
  -links n 擁有n個(gè)鏈接
  -ls 類似ll的樣子輸出
  -mtime n n天前改過(guò)
  -perm 選定權(quán)限
  -name 'pattern'
  -size n +n -n 大小為n,大于n,小于n,+-適用于其他選項(xiàng)
  -type t d為目錄,f為文件,l為鏈接
  -user u 選定用戶

xargs命令

之所以能用到這個(gè)命令,關(guān)鍵是由于很多命令不支持|管道來(lái)傳遞參數(shù),而日常工作中有有這個(gè)必要,所以就有了xargs命令,例如:

  find /sbin -perm +700 |ls -l       這個(gè)命令是錯(cuò)誤的
  find /sbin -perm +700 |xargs ls -l   這樣才是正確的

df命令

df (disk free) 提供單行摘要,一行顯示一個(gè)加載的文件系統(tǒng)的已使用和可用空間,默認(rèn)是整個(gè)系統(tǒng)

  df -k 按照KB來(lái)顯示
  df -h 按照用戶最易讀懂的方式來(lái)顯示
  df -i 按照inode來(lái)顯示

inode:文件數(shù)據(jù)都儲(chǔ)存在"塊"中,那么很顯然,我們還必須找到一個(gè)地方儲(chǔ)存文件的元信息,比如文件的創(chuàng)建者、文件的創(chuàng)建日期、文件的大小等等。這種儲(chǔ)存文件元信息的區(qū)域就叫做inode,中文譯名為"索引節(jié)點(diǎn)"。

每個(gè)inode節(jié)點(diǎn)的大小,一般是128字節(jié)或256字節(jié)。inode節(jié)點(diǎn)的總數(shù),在格式化時(shí)就給定,一般是每1KB或每2KB就設(shè)置一個(gè)inode。假定在一塊1GB的硬盤(pán)中,每個(gè)inode節(jié)點(diǎn)的大小為128字節(jié),每1KB就設(shè)置一個(gè)inode,那么inode table的大小就會(huì)達(dá)到128MB,占整塊硬盤(pán)的12.8%。

stat命令查看inode信息

du命令

du用來(lái)提供一個(gè)目錄的已經(jīng)使用空間,默認(rèn)是遞歸當(dāng)前目錄

  du -k 按kb顯示
  du -s 不遞歸,僅顯示當(dāng)前目錄
  du -h 以友好形式輸出,就是會(huì)自動(dòng)換算成GB,MB等
  du -h -s /var/log /var/tmp
  200M /var/log
  8.0k /var/tmp

cmp命令和diff命令

cmp命令告訴你第一個(gè)不同的位置并且返回一個(gè)失敗離開(kāi)碼

diff則會(huì)詳細(xì)告訴你不同點(diǎn)在哪里

md5sum命令

  md5sum file1 file2 file3 ...
  可以列出各個(gè)文件的md5值,注意inode和文件是分開(kāi)的,所以只要內(nèi)容一樣就可以了

擴(kuò)展實(shí)例:合并用戶數(shù)據(jù)庫(kù)

合并兩個(gè)server的/etc/passwd

tee命令

在使用管道時(shí)往標(biāo)準(zhǔn)輸出也顯示

echo hello | tee file

拼寫(xiě)檢查

spell,ispell等等,以及awk寫(xiě)的

第十三章:進(jìn)程

ps命令

  ps -l 長(zhǎng)輸出
  ps -e 顯示所有進(jìn)程,否則只是當(dāng)前進(jìn)程

另外top命令動(dòng)態(tài)顯示

kill命令

kill其實(shí)是傳送信號(hào)(signal)給指定的執(zhí)行中的進(jìn)程。

kill的用法應(yīng)該是

kill -signal pid

舉個(gè)例子:

  kill -STOP 17787
  sleep 3600 && kill -CONT 17787 &
  把17787暫停,然后一小時(shí)后繼續(xù)啟動(dòng),&表示這條命令放到后臺(tái)運(yùn)行

kill 的默認(rèn)信號(hào)是 kill -TERM

trap 命令

trap是一個(gè)shell內(nèi)建命令,它用來(lái)在腳本中指定信號(hào)如何處理。
比如,按Ctrl+C會(huì)使腳本終止執(zhí)行,實(shí)際上系統(tǒng)發(fā)送了SIGINT信號(hào)給腳本進(jìn)程,
SIGINT信號(hào)的默認(rèn)處理方式就是退出程序。如果要在Ctrl+C不退出程序,
那么就得使用trap命令來(lái)指定一下SIGINT的處理方式了。
trap命令不僅僅處理Linux信號(hào),還能對(duì)腳本退出(EXIT)、
調(diào)試(DEBUG)、錯(cuò)誤(ERR)、返回(RETURN)等情況指定處理方式。

舉個(gè)例子

  在進(jìn)程號(hào)為24286的進(jìn)程中:
  trap 'echo Ignoring HUP' HUP
  $ kill -HUP 24286
  $ Ignoring HUP

兩個(gè)信號(hào)不能捕捉,一個(gè)是KILL,一個(gè)是STOP

進(jìn)程系統(tǒng)調(diào)用的追蹤

系統(tǒng)調(diào)用(英語(yǔ):system call),又稱為系統(tǒng)呼叫,
指運(yùn)行在使用者空間的程序向操作系統(tǒng)內(nèi)核請(qǐng)求需要更高權(quán)限運(yùn)行的服務(wù)。
系統(tǒng)調(diào)用提供用戶程序與操作系統(tǒng)之間的接口。
大多數(shù)系統(tǒng)交互式操作需求在內(nèi)核態(tài)執(zhí)行。如設(shè)備IO操作或者進(jìn)程間通信。

比如fork,exit,getpid等等都是系統(tǒng)調(diào)用

有一些命令可以跟蹤某個(gè)程序的系統(tǒng)調(diào)用,比如trace等等

延遲的進(jìn)程調(diào)度

  1. sleep

  2. at:指定時(shí)間

  3. batch:加入批處理隊(duì)列

  4. crontab:重復(fù)執(zhí)行某些工作

Shell可移植性議題與擴(kuò)展

本章比較了ksh和bash的異同點(diǎn)

set命令

set命令作用主要是顯示系統(tǒng)中已經(jīng)存在的shell變量,
以及設(shè)置shell變量的新變量值。

set +o 列出所有已經(jīng)設(shè)置的shell變量,這里的變量感覺(jué)更像是一些配置

bash另外有shopt命令來(lái)配置shell變量

在ksh中執(zhí)行set顯示出來(lái)完全不同,所以是當(dāng)前shell的配置,個(gè)人理解

第十五章:安全的shell腳本:起點(diǎn)

一個(gè)有趣的木馬,假設(shè)PATH第一個(gè)為~lxc/bin,當(dāng)lxc以sudo grep運(yùn)行時(shí),
就執(zhí)行了nusty stuff

  /bin/grep "$@"
  case $(whoami) in
  root) nasty stuff
        rm ~lxc/bin/grep
        ;;
  esac
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,237評(píng)論 6 537
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,957評(píng)論 3 423
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 177,248評(píng)論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,356評(píng)論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,081評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,485評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,534評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,720評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,263評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,025評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,204評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,787評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,461評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,874評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,105評(píng)論 1 289
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,945評(píng)論 3 395
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,205評(píng)論 2 375

推薦閱讀更多精彩內(nèi)容