Unix基礎(chǔ)環(huán)境變量

      網(wǎng)友投稿 895 2022-05-29

      前言:

      第一招 HelloWorld:

      echo -n # 不帶換行

      devzkndeMacBook-Pro:~ devzkn$ echo -n hello kevin

      hello kevindevzkndeMacBook-Pro:~ devzkn$

      第二招 判斷:

      第一式:if

      if true

      then

      echo "Hello World"

      else

      echo "Bug"

      fi

      if false

      then

      echo "Hello World"

      elif true

      then

      echo "Bug"

      else

      echo "Bee"

      fi

      判斷原理

      if、elif會(huì)執(zhí)行它后面跟著的命令,然后看返回值是否為0,如果為0則執(zhí)行then下面的語句塊,否則執(zhí)行else下面的語句塊。

      devzkndeMacBook-Pro:~ devzkn$ true

      devzkndeMacBook-Pro:~ devzkn$ echo $?

      0

      devzkndeMacBook-Pro:~ devzkn$ false

      devzkndeMacBook-Pro:~ devzkn$ echo $?

      1

      devzkndeMacBook-Pro:~ devzkn$

      true、false事實(shí)上也為一個(gè)命令,true的返回碼必為0,false的返回碼必為1

      $?為shell內(nèi)置變量,用于存放上一個(gè)命令的返回碼

      第二式:test、[ ] 和 [[ ]]

      test、[ ]、[[ ]]實(shí)際上都是shell中的命令,執(zhí)行之后會(huì)返回1或0,而這幾個(gè)命令與if相結(jié)合可以達(dá)到我們所需要的許多判斷功能,例如測(cè)試字符串是否為空的三種寫法

      s=""

      if [ -z ${s} ]

      then

      echo "empty"

      fi

      if [[ -z ${s} ]]

      then

      echo "empty"

      fi

      if test -z ${s}

      then

      echo "empty"

      fi

      示例:

      devzkndeMacBook-Pro:test devzkn$ cat test.sh

      s=;

      if test -z ${s}

      then

      echo "empty"

      fi

      devzkndeMacBook-Pro:test devzkn$ sh -x test.sh

      + s=

      + test -z

      + echo empty

      empty

      devzkndeMacBook-Pro:test devzkn$ sh -x test.sh s

      + s=s

      + test -z s

      devzkndeMacBook-Pro:test devzkn$

      ps:1. 在性能方面 [ ] 和 test 性能基本相同, [[ ]] 性能是最高的,為前兩者的 5 倍左右(以 -d 運(yùn)算符測(cè)試),所以建議盡量使用 [[ ]] 提高腳本性能。

      2. 如果是在 [ ] 中使用 < 和 > ,需要將它們寫成 \< 和 \>

      其他請(qǐng)?jiān)斠?man test

      第三式:&&、||

      &&可以用來對(duì)兩個(gè)判斷語句求與;注:只有[[ ]]才允許把&&,||寫在里面

      小技巧

      &&、||還可以用來拼接命令,達(dá)到按前一個(gè)命令成功與否來決定是否執(zhí)行后一個(gè)命令的效果

      cd /data && ls # 當(dāng)`cd /data`返回0(即成功)時(shí)才執(zhí)行后面的`ls`

      cd /data || cd /root # 當(dāng)`cd /data`返回非0(即失敗)時(shí)才執(zhí)行后面的`cd /root`

      示例:

      devzkndeMacBook-Pro:test devzkn$ cd ../? &&ls

      Desktop Library Pictures mydoc

      Documents Movies Public test

      Downloads Music demand

      devzkndeMacBook-Pro:~ devzkn$ cd test1 || cd test

      -bash: cd: test1: No such file or directory

      devzkndeMacBook-Pro:test devzkn$

      第三招:循環(huán)

      第一式:for

      第一式:for

      for i in {1..100}

      do

      echo ${i}

      done

      注:

      {1..100}屬于通配的一種寫法,展開會(huì)是1 2 3 ... 100(1~100以空格隔開)這樣的字串。

      例如for i in 1 2 3;這樣的語句,for會(huì)將1、2、3依次賦值于i進(jìn)行循環(huán),而對(duì)于通配的情況,for則會(huì)將通配展開后將里面的每一項(xiàng)依次賦值于i進(jìn)行循環(huán)。

      示例1:

      devzkndeMacBook-Pro:test devzkn$ cat test_for.sh

      for i in {1..11}

      do

      echo ${i}

      done

      devzkndeMacBook-Pro:test devzkn$ sh test_for.sh

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      示例2:

      cd ~/trc/ for webxxx in `cat ~/kevin/` do # zmore $webxxx |awk -f ~/kevin/rmline.awk| grep xxxx.action |grep -E " [0-9]+\** " | awk -F '[' '{print ,,}'|sed 's/];發(fā)送://'|sed 's/]//' #more $webxxx |awk -f ~/kevin/rmline.awk| grep xxxx.action |grep -E " [0-9]+\** " | awk -F '[' '{print ,,}'|sed 's/];發(fā)送://'|sed 's/]//' #more $webxxx |awk -f ~/kevin/rmline.awk| grep 2201194.d |grep -E " [0-9]+\** " | awk -F '[' '{print ,,}'|sed 's/];發(fā)送://'|sed 's/]//' more $webxxx |awk -f ~/kevin/rmline.awk| grep xxx.d |grep -E " [0-9]+\** " | awk -F '[' '{print ,,}'|sed 's/];發(fā)送://'|sed 's/]//' done

      反引號(hào)(`)之間的命令會(huì)被執(zhí)行,其輸出結(jié)果會(huì)轉(zhuǎn)換成一個(gè)變量

      ps: 可使用seq 序列命令

      seq -- print sequences of numbers

      devzkndeMacBook-Pro:test devzkn$ cat test_for.sh

      for i in `seq 1 3 20`

      do

      echo ${i}

      done

      devzkndeMacBook-Pro:test devzkn$ sh test_for.sh

      1

      4

      7

      10

      13

      16

      19

      for ((i = 0; i < 100; i++))

      do

      echo ${i}

      done

      for ((i = 0; i < 100; i+= 2))

      do

      echo ${i}

      done

      注:

      以上與C語言式的for循環(huán)語法基本相同,區(qū)別在于雙重括號(hào):(( ))

      第二式:while、until

      i=0

      while [[ ${i} -lt 100 ]]

      do

      echo ${i}

      ((i++))

      done

      i=0

      until [[ ${i} -ge 100 ]]

      do

      echo ${i}

      ((i++))

      done

      注:

      while和until的判斷原理與if是類似的,它會(huì)執(zhí)行并它后面跟著的命令,不同點(diǎn)在于:

      while是后面語句返回值為0,則執(zhí)行循環(huán)中的語句塊,否則跳出循環(huán);

      until則是后面語句返回值非0,則執(zhí)行循環(huán)中的語句塊,否則跳出循環(huán)。

      第四招:變量

      第一式:整數(shù)

      整數(shù)的運(yùn)算

      方法較多,此處只列舉最淺顯易懂,并且效率最高的辦法——直接將符合C語言語法的表達(dá)式放到(( ))中即可達(dá)到對(duì)整數(shù)的計(jì)算目的:

      echo $(( 1+1 )) # 最簡(jiǎn)單的1+1

      echo $(( (1+2)*3/4 )) # 表達(dá)式中還可以帶括號(hào)

      echo $(( 1<<32 )) # 左移右移也支持,但僅限于-4294967296~4294967296之間的數(shù)值

      echo $(( 1&3 )) # &、^、|、~ 這樣的位操作亦支持

      (( i=1+2 )) # 將1+2計(jì)算出結(jié)果后賦值給i,后續(xù)若`echo ${i}`會(huì)得到3

      (( i++ )) # 變量i自增1

      (( i+=3 )) # 變量i自增3

      # ... # 還有很多,不再詳列

      注:

      進(jìn)行整數(shù)運(yùn)算的方法還有:expr、$[]、let等shell等內(nèi)置命令,也可調(diào)用bc、python等外部工具進(jìn)行更復(fù)雜的數(shù)學(xué)運(yùn)算

      第二式:字符串

      devzkndeMacBook-Pro:test devzkn$ s="i hate hate kevin\!"

      devzkndeMacBook-Pro:test devzkn$ echo $s

      i hate hate kevin\!

      devzkndeMacBook-Pro:test devzkn$ echo ${s/hate/love}

      i love hate kevin\!

      devzkndeMacBook-Pro:test devzkn$ s="i hate hate kevin"

      devzkndeMacBook-Pro:test devzkn$ echo ${s//hate/love}

      i love love kevin

      通配刪除,即按通配符,刪除掉字符串中符合條件的一部分

      注:

      此處通配規(guī)則參考通配符一覽表

      最小通配和最大通配的區(qū)別: ????最小通配:符合通配的最小子串 ????最大通配:符合通配的最大子串 例如string值為/00/01/02/dir,對(duì)于通配/*/,其最小通配為/00/,而最大通配/00/01/02/

      小技巧

      獲取文件名:${path##*/}?(相當(dāng)于basename命令的功能)

      獲取目錄名:${path%/*}?(相當(dāng)于dirname命令的功能)

      獲取后綴名:${path##*.}

      devzkndeMacBook-Pro:test devzkn$ s="/Users/devzkn/test.sh"

      devzkndeMacBook-Pro:test devzkn$ echo ${s##*/}

      test.sh

      devzkndeMacBook-Pro:test devzkn$ echo ${s%/*}

      /Users/devzkn

      devzkndeMacBook-Pro:test devzkn$ echo ${s##*.}

      sh

      第三式:數(shù)組

      普通數(shù)組

      a=() # 空數(shù)組

      a=(1 2 3) # 元素為1,2,3的數(shù)組

      echo ${#a[*]} # 數(shù)組長(zhǎng)度

      echo ${a[2]} # 下標(biāo)為2的元素值(下標(biāo)從0開始)

      a[1]=0 # 給下標(biāo)為1的元素賦值

      # 遍歷數(shù)組

      for i in ${a[*]}

      do

      echo ${i}

      done

      unset a # 清空數(shù)組

      關(guān)聯(lián)數(shù)組

      關(guān)聯(lián)數(shù)組可以用于存儲(chǔ)key-value型的數(shù)據(jù),其功能相當(dāng)于C++中的map或python中的dict。

      declare -A a # 聲明關(guān)聯(lián)數(shù)組(必須有此句)

      a=(["apple"]="a1" ["banana"]="b2" ["carrot"]="c3") # 初始化關(guān)聯(lián)數(shù)組

      echo ${#a[*]} # 獲取元素個(gè)數(shù)

      echo ${a["carrot"]} # 獲取元素值

      a["durian"]="d4" # 插入或修改元素

      echo ${!a[*]} # 獲取所有的key

      unset a["banana"] # 刪除元素

      # 遍歷數(shù)組(僅value)

      for i in ${a[*]}

      do

      echo ${i}

      done

      # 遍歷數(shù)組(key和value)

      for key in ${!a[*]}

      do

      echo "${key} ==> ${a[${key}]}"

      done

      unset a # 清空數(shù)組

      注:

      關(guān)聯(lián)數(shù)組需要bash 4.0以上版本才支持,選用需慎重。查看bash版本用bash --version

      關(guān)聯(lián)數(shù)組必須用declare -A顯示聲明類型,否則數(shù)值會(huì)出錯(cuò)。

      第四式:將命令執(zhí)行結(jié)果存入變量

      LINE_CNT=`wc -l test.txt`

      LINE_CNT=$(wc -l test.txt)

      以上命令均可把wc -l test.txt的結(jié)果存入LINE_CNT變量中

      注:?` `?和$( )都只將命令行標(biāo)準(zhǔn)輸出的內(nèi)容存入變量,如果需要將標(biāo)準(zhǔn)錯(cuò)誤內(nèi)容存入變量,需要用到重定向。

      如果命令執(zhí)行結(jié)果有多行內(nèi)容,存入變量并打印時(shí)換行符會(huì)丟失:

      devzkndeMacBook-Pro:test devzkn$ ls test.sh test_for.sh devzkndeMacBook-Pro:test devzkn$ cat test_for.sh for i in `seq 1 3 20` do echo ${i} done devzkndeMacBook-Pro:test devzkn$ content=`cat test_for.sh` devzkndeMacBook-Pro:test devzkn$ echo ${content} for i in `seq 1 3 20` do echo ${i} done devzkndeMacBook-Pro:test devzkn$

      若需要保留換行符,則在打印時(shí)必須加上 "" :

      devzkndeMacBook-Pro:test devzkn$ echo "${content}"

      for i in `seq 1 3 20`

      do

      echo ${i}

      done

      devzkndeMacBook-Pro:test devzkn$

      正文(重點(diǎn))

      第五招:重定向

      標(biāo)準(zhǔn)輸入流、標(biāo)準(zhǔn)輸出流、標(biāo)準(zhǔn)錯(cuò)誤流

      重定向方式一覽表

      第一式:重定向標(biāo)準(zhǔn)輸出流(stdout)

      把程序打印的內(nèi)容輸出到文件

      devzkndeMacBook-Pro:test devzkn$ echo 1+1 >exp.txt

      devzkndeMacBook-Pro:test devzkn$ cat exp.txt

      1+1

      第二式:重定向標(biāo)準(zhǔn)錯(cuò)誤流(stderr)

      把程序的錯(cuò)誤信息輸出到文件

      devzkndeMacBook-Pro:test devzkn$ ls +++ 2> err*

      devzkndeMacBook-Pro:test devzkn$ cat err*

      ls: +++: No such file or directory

      第三式:重定向標(biāo)準(zhǔn)輸入流(stdin)

      1. 讓程序從文件讀取輸入

      以默認(rèn)從標(biāo)準(zhǔn)輸入讀取表達(dá)式,并進(jìn)行數(shù)學(xué)計(jì)算的命令bc為例:

      devzkndeMacBook-Pro:test devzkn$ echo 1+1 >exp.txt

      devzkndeMacBook-Pro:test devzkn$ cat exp.txt

      1+1

      devzkndeMacBook-Pro:test devzkn$ bc -q < exp.txt

      2

      2. 將變量中內(nèi)容作為程序輸入

      devzkndeMacBook-Pro:test devzkn$ s="1+1"

      devzkndeMacBook-Pro:test devzkn$ bc -q <<< "${s}"

      2

      3. 將當(dāng)前shell腳本中的多行內(nèi)容作為程序的輸入

      例如在shell中內(nèi)嵌多行python代碼:

      devzkndeMacBook-Pro:test devzkn$ cat test_python.sh

      python << EOF

      print 'hello from python'

      print 'hello'+'kevin'

      EOF

      devzkndeMacBook-Pro:test devzkn$ sh test_python.sh

      hello from python

      hellokevin

      內(nèi)容中支持shell變量

      devzkndeMacBook-Pro:test devzkn$ cat test_python.sh

      #python << EOF

      #print 'hello from python'

      #print 'hello'+'kevin'

      #EOF

      msg="shell variable"

      python <

      print '${msg}'

      EOF

      devzkndeMacBook-Pro:test devzkn$ sh test_python.sh

      shell variable

      ps:

      以上重定向方法格式為:命令 << EOF (換行)...(換行) EOF,其中的EOF換成其它字符串也是有效的,如:命令 << ABC (換行)...(換行) ABC的,但通用習(xí)慣都使用EOF

      第六招:管道

      一式:管道的基本功能

      管道的寫法為?cmd1 | cmd2,功能是依次執(zhí)行cmd1和cmd2,并將cmd1的標(biāo)準(zhǔn)輸出作為cmd2的標(biāo)準(zhǔn)輸入

      第二式:管道與while、read組合

      devzkndeMacBook-Pro:test devzkn$ cat test_while.sh

      line_no=0

      cat test.sh |

      while read line

      do

      ((line_no++));

      echo "${line_no} ${line}"

      done

      #echo "${line_no}"

      devzkndeMacBook-Pro:test devzkn$ sh test_while.sh

      1 s=;

      2 if test -z ${s}

      3

      4 then

      5 echo "empty"

      6

      7 fi

      注:

      read命令用于從標(biāo)準(zhǔn)輸入讀取一行并賦值給一個(gè)或多個(gè)變量,如read LINE會(huì)從標(biāo)準(zhǔn)輸入讀取一行并將整行內(nèi)容賦值給LINE變量,read A B則會(huì)從標(biāo)準(zhǔn)輸入讀入一行并將這行的第1、2列分別賦值給A、B兩個(gè)變量(分割符默認(rèn)為空格或tab,可給IFS賦值來更改分割符) > 2. 末尾注釋掉的echo "${LINE_NO}"若執(zhí)行會(huì)輸出0,原因是管道中的while語句是執(zhí)行在子進(jìn)程中的,不會(huì)改變父進(jìn)程中LINE_NO變量的值

      IFS(Internal Field Seprator),即內(nèi)部域分隔符,完整定義是“The shell uses the value stored in IFS, which is the space, tab, and newline characters by default, to delimit words for the read and set commands, when parsing output from command substitution, and when performing variable substituioin.”。

      第三式:管道與xargs組合

      devzkndeMacBook-Pro:test devzkn$ find . -type f -name \*.txt

      ./err.txt

      ./exp.txt

      devzkndeMacBook-Pro:test devzkn$ find . -type f -name \*.txt | xargs

      ./err.txt ./exp.txt

      xargs直接接命令名稱,則將從標(biāo)準(zhǔn)輸入讀取的所有內(nèi)容合并為一行構(gòu)建命令行并執(zhí)行

      devzkndeMacBook-Pro:test devzkn$ find . -type f -name \*.txt | xargs ls -l

      -rw-r--r--? 1 devzkn? staff? 35 11? 1 22:03 ./err.txt

      -rw-r--r--? 1 devzkn? staff ? 4 11? 1 22:08 ./exp.txt

      xargs加上-i參數(shù),則會(huì)每讀取一行就構(gòu)建并執(zhí)行一個(gè)命令行,構(gòu)建命令行時(shí)會(huì)將{}替換為該行的內(nèi)容

      有待嘗試

      [casheywen@ubuntu:~]# cat test.txt | xargs -i echo rm {}

      rm a

      rm b

      Unix基礎(chǔ)之環(huán)境變量

      rm c

      第七招:通配

      hell通配的原理

      如果你的當(dāng)前目錄中有1.txt 2.txt 3.txt三個(gè)文件,那么當(dāng)你執(zhí)行l(wèi)s *.txt這條命令,shell究竟為你做了什么?

      其實(shí)shell會(huì)先讀取當(dāng)前目錄,然后按*.txt的通配條件過濾得到1.txt 2.txt 3.txt這個(gè)文件列表,然后將這個(gè)列表作為參數(shù)傳給ls,即ls *.txt相當(dāng)于ls 1.txt 2.txt 3.txt,ls命令本身并不會(huì)得到*.txt這樣的參數(shù)。

      所以如果需要列出當(dāng)前目錄中所有的txt文件,我們使用echo *.txt也同樣可以達(dá)到目的:

      devzkndeMacBook-Pro:test devzkn$ echo *.txt

      err.txt exp.txt

      注:對(duì)于{ }通配shell不會(huì)讀取目錄并過濾獲得文件列表。詳細(xì)請(qǐng)參考下文 。

      通配符一覽表

      注:

      *、?、[ ]的通配都會(huì)按讀取目錄并過濾的方式展開通配項(xiàng)目

      { }則不會(huì)有讀取目錄的過程,它是通過枚舉所有符合條件的通配項(xiàng)直接展開的

      devzkndeMacBook-Pro:test devzkn$ ls -l {e..f}*.txt

      ls: f*.txt: No such file or directory

      -rw-r--r--? 1 devzkn? staff? 35 11? 1 22:03 err.txt

      -rw-r--r--? 1 devzkn? staff ? 4 11? 1 22:08 exp.txt

      devzkndeMacBook-Pro:test devzkn$ echo {e..f}*.txt

      err.txt exp.txt f*.txt

      devzkndeMacBook-Pro:test devzkn$

      由上面的命令可見,*通配的結(jié)果與目錄中存在哪些文件有關(guān)系,而{ }的通配結(jié)果與目錄中存在哪些文件無關(guān)。若用{ }進(jìn)行通配,則有可能將不存在的文件路徑作為命令行參數(shù)傳給程序。

      第一式:*

      *用于通配文件名或目錄名中某一部分為任意內(nèi)容:

      第二式:[ ]

      [ ]用于通配文件名或目錄名中某個(gè)字符為限定范圍內(nèi)或限定范圍外的值:

      第三式:?

      ?用于通配文件名中某處一個(gè)任意值的字符:

      第四式:{ }

      { }也為通配符,用于通配在它枚舉范圍內(nèi)的值,由于它是直接展開的,我們可以將它用于批量創(chuàng)建目錄或文件,也可以用于生成序列:

      生成序列

      { }生成的序列常用于for循環(huán)

      for ip in 192.168.234.{1..255}

      do

      ping ${ip} -w 1 &> /dev/null && echo ${ip} is Alive

      done

      以上例子用于查找192.168.234.1~192.168.234.255整個(gè)網(wǎng)段能ping通的所有ip

      1.1查看環(huán)境變量

      env 顯示所有的環(huán)境變量設(shè)置

      devzkndeMacBook-Pro:test devzkn$ env

      TERM_PROGRAM=Apple_Terminal

      SHELL=/bin/bash

      TERM=xterm-256color

      echo $ENV_VARIABLE ?顯示指定環(huán)境變量的設(shè)置

      例:

      echo $PATH

      /bin:/etc:/usr/bin:/tcb/bin

      1.2 設(shè)定環(huán)境變量

      $ ENV_VARIABLE=XXX;export ENV_VARIABLE

      例:

      $ PATH=$PATH:$INFORMIXDIR/bin;export PATH ?將環(huán)境變量PATH設(shè)定為原PATH值+$INFORMIXDIR/bin

      1.3 取消環(huán)境變量設(shè)置

      $ unset $ENV_VARIABLE

      例:

      $ set GZJ=gzj;export GZJ ?設(shè)置環(huán)境變量GZJ

      $ echo $GZJ

      gzj ?顯示環(huán)境變量值

      $ unset $GZJ ?取消環(huán)境變量GZJ的設(shè)置

      $ echo $GZJ

      已取消

      總結(jié)

      Python UNIX

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:重溫C語言,這三十多個(gè)細(xì)節(jié)你把握住了?
      下一篇:UNIX 環(huán)境高級(jí)編程|進(jìn)程控制(上)
      相關(guān)文章
      国产精品高清视亚洲精品| 好看的亚洲黄色经典| 亚洲AV无码专区在线播放中文 | 911精品国产亚洲日本美国韩国| 亚洲日韩aⅴ在线视频| 久久精品亚洲乱码伦伦中文| 亚洲不卡AV影片在线播放| 亚洲成人影院在线观看| jizzjizz亚洲| 亚洲国产成人久久综合野外| 亚洲高清无码专区视频| 亚洲午夜无码片在线观看影院猛| 无码不卡亚洲成?人片| 亚洲&#228;v永久无码精品天堂久久 | 亚洲黄网站wwwwww| 亚洲综合激情九月婷婷| 亚洲成在人线电影天堂色| 亚洲AV无码一区二区三区在线| 亚洲日本人成中文字幕| 亚洲综合av一区二区三区不卡| 亚洲欧洲专线一区| 少妇亚洲免费精品| 久久久久噜噜噜亚洲熟女综合 | 亚洲精品免费网站| 亚洲男同gay片| 人人狠狠综合久久亚洲高清| 亚洲视频一区二区| 亚洲AV无码成人精品区蜜桃| 久久久亚洲欧洲日产国码aⅴ| 亚洲国产高清在线精品一区| 中文字幕亚洲综合久久综合| 精品亚洲成a人在线观看| 亚洲AV网站在线观看| 亚洲中文字幕无码久久综合网| 国产亚洲综合网曝门系列| 亚洲一区二区电影| 亚洲一区二区久久| 久久久久久久久无码精品亚洲日韩| 亚洲色一色噜一噜噜噜| 久久青青成人亚洲精品| 亚洲毛片一级带毛片基地|