02_shell_引號與運算符

引號

 引號的必要性
 變量和替換操作,在腳本中執行變量替換時,最容易犯的一個錯誤就是引號的錯誤

==雙引號
   雙引號 使用雙引號可以引用除字符$,`反引號,\反斜槓外的任意字符或者字符串
hzmct@U-64:/study/linuxtest/day03$ echo -e "hello world,$SHELL"
hello world,/bin/bash

==單引號
   單引號 單引號與雙引號類似,不同的是shell會忽略任何引用值。換句話說,如果屏蔽了其特殊含義,會將引號裏的所有字符,包括引號都作爲一個字符。
   echo -e ' hello world, $SHELL '\n* wangbaoming '  
   結論:單引號讓特殊字符失去意義。
hzmct@U-64:/study/linuxtest/day03$ echo -e "hello world,$SHELL "
hello world,/bin/bash 
hzmct@U-64:/study/linuxtest/day03$ echo -e 'hello world,$SHELL'
hello world,$SHELL

==反引號
   反引號 反引號用於設置系統命令的輸出到變量。shell將反引號中的內容作爲一個系統命令,並執行其內容
echo "hzmct `echo $PATH`"
hzmct /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/lib/oracle/11.2/client64/bin

==反斜槓
   反斜槓
   如果一個字符有特殊含義,反斜槓防止shell誤解其含義,即:屏蔽其特殊含義。
   ECHO下屬字符含有特殊含義:$ * + ^ ` ‘’ | ?
   eg:echo * echo \*

hzmct@U-64:$ echo *hello*
*hello*
hzmct@U-64:$ echo *hello *
*hello 1.sh 1.txt 1weizhi.sh 2find.sh exec.sh grep.out readonline.sh read.sh testdir1.sh testdir.sh who.out
hzmct@U-64:$ echo *hello \*
*hello *
hzmct@U-64:$

表達式類型

   按位運算符
   ~op1 反運算符
   op1<<op2    左移運算符
   op1>>op2    右移運算符
   op1 & op2   與比較運算符 
   op1 ^ op2   異或運算符
   op1 | op2   或運算符
   eg: echo $[2<<4]  echo $[2^4]
   $[ ] 表示形式告訴shell對方括號中的表達式求值
eg: echo $[3+9] 

   邏輯運算符
   && 邏輯與運算
   || 邏輯或運算符 echo $[1||1]
   賦值運算符
   =,+=,-=,*=,/=,%=,&=,^=、|=,<<=,>>=
   let count = $count + $change
   let count += $change

let 執行算術運算並將結果賦給一個變量

hzmct@U-64:/study/linuxtest/day03$ var=10
hzmct@U-64:/study/linuxtest/day03$ let var+=10
hzmct@U-64:/study/linuxtest/day03$ echo $var
20

表達式替換

$[] 和 $(( ))  習慣使用$[],所有shell的求值都是用整數完成
   $[]可以接受不同基數的數字
   [base#n]    n表示基數從2到36任意基數
 [wbm@wmblinux64 myshell]$ echo $[10#8+191] 
199

hzmct@U-64:$ echo $[2#1+10]
11
hzmct@U-64:$ echo $[2#2+10]
bash: 2#2: value too great for base (error token is "2#2")
hzmct@U-64:/study/linuxtest/day03$ echo $[2#0+10]
10
    運算符的優先級(不確定的地方,多加括號)
方法一:使用let命令
hzmct@U-64:$ var=10
hzmct@U-64:$ let var+=10
hzmct@U-64:$ echo $var
20
方法2:使用雙圓括號
hzmct@U-64:~$ v1=$(( 4*5))
hzmct@U-64:~$ echo $v1
20

shell輸入與輸出


echo

終端用戶登錄linux服務器,爲每一個終端用戶啓動一個shell程序。
   echo命令可以顯示文本行或變量,或者把字符串輸入到文件。
   echo [option] string
   -e  解析轉義字符 
   -n  回車不換行,linux系統默認回車換行 eg: echo –n “abc” ; echo “abc” 
   -轉義字符(\c(回車不換行) \f(禁止)\t(回車換行) \n(回車換行))

例子
  1 #!/bin/bash
  2 #echo
  3 echo -e "hello world...\n\n\n"
  4 echo "ok"
  5 echo "空,後面沒有任何東西,將要有一個回車換行"
  6 echo
  7 echo -n "asdf"
  8 echo "echo -e 解析轉義字符 -n 回車不換行">mylog.txt


read

read語句可以從鍵盤或文件的某一行文本中讀入信息,並將其制複製給一個變量。
   read var1 var2 ….   若只指定了一個變量,那麼read將會把所有的輸入賦給該變量,直至遇上第一個文件結束符或者回車。如果給了多個變量,他們按照順序分別賦予不同的變量。shell將用空格作爲變量之間的分隔符。


例子
  1 #!/bin/bash
  2 #注意回車不換行的用法
  3 echo -n "First Name:"
  4 read firstname
  5 echo -n "Last Name:"
  6 read lastname lastname2
  7 echo -e "FirstName:${firstname}\n"
  8 echo -e "LastName:${lastname}\n"
  9 echo -e "LastName2:${lastname2}\n"

hzmct@U-64:/study/linuxtest/day03$ ./4read.sh 
First Name:aa
Last Name:vv bb cc
FirstName:aa

LastName:vv

LastName22:bb cc

hzmct@U-64:/study/linuxtest/day03$

cat

   cat 是一個簡單而通用的命令,可用它顯示文件內容、創建文件、還可以用它來顯示控制字符。
   cat [options] filename1 … filename2 ….
   -v 顯示控制字符
   使用cat命令時注意,它不會在文件分頁處停下來;它會一下顯示完整個文件。如果希望每次顯示一頁,可以使用more命令 或把cat命令的輸出通過管道傳遞到另外一個具有分頁功能的命令(more、less)中。
   man cat

//顯示控制字符
hzmct@U-64:/study/linuxtest/day03$ cat -v 3.txt 
pwd
echo -e M-hM-'M-#M-fM-^^M-^PM-hM-=M-,M-dM-9M-^IM-eM--M-^WM-gM-,M-& -n M-eM-^[M-^^M-hM-=M-&M-dM-8M-^MM-fM-^MM-"M-hM-!M-^L

//連續查看2 個文件
hzmct@U-64:/study/linuxtest/day03$ cat 1.txt mylog.txt ;
pwd
echo -e 解析轉義字符 -n 回車不換行

//將1.txt mylog.txt輸入到3.txt,若3.txt不存在則創建
hzmct@U-64:/study/linuxtest/day03$ cat 1.txt mylog.txt >3.txt


管道

   可以通過管道把一個命令的輸出傳遞給另外一個命令做輸入。管道用豎線表示
   格式:命令1 | 命令2
   cat myfile | more
   ls –l | grep “myfile” 
   df –k | awk ‘{print $1}’ | grep –v “Filesystem文件系統” 
   df –k 看磁盤空間 查找第一列 去除filesystem字符排除掉

tee將輸出同時發送到顯示器和文件

   tee 命令把結果輸出到標準輸出,另一個副本輸出到相應文件
   tee –a file     -a: 表示追加 不加-a表示覆蓋
   該命令一般用於管道之後  (一般看到輸出,並存文件)
   eg  who | tee –a who.out 
   df –k | awk ‘{print $1}’ | grep –v “Filesystem” | tee partation.txt


//例子
hzmct@U-64:/study/linuxtest/day03$ cat 3.txt |tee -a tee.log
pwd
echo -e 解析轉義字符 -n 回車不換行
hzmct@U-64:/study/linuxtest/day03$ cat tee.log 
pwd
echo -e 解析轉義字符 -n 回車不換行

標準輸入、標準輸出和錯誤

當我們在shell中執行命令的時候,每個進程都和三個打開的文件相聯繫,並使用文件描符來引用   這些文件。由於文件描述符不容易記憶, shell同時也給出了相應的文件名。
下面就是這些文件描述符及它們通常所對應的文件名:
輸入文件—標準輸入 0
輸出文件—標準輸出 1
錯誤輸出文件—標準錯誤 2
系統中實際上有12個文件描述符,但是正如我們在上表中所看到的,012是標準輸入、出和錯誤。可以任意使用文件描述符39

文件重定向

文件重定向:改變程序運行的輸入來源和輸出地點

這裏寫圖片描述

==重定向標準輸出

$ cat 1.txt|sort 1>sort.out
$ cat 1.txt|sort>sort.out  這兩個命令相同,不寫默認爲1
$ pwd>>1.txt

//創建長度爲0的空文件
$ >1.txt
==重定向標準輸入

eg1:    
sort<filefile的內容輸入到sort進行排序,排序後的結果sort命令輸出
hzmct@U-64:/study/linuxtest/day03$ cat 1.txt
/study/linuxtest/day03
11\n22\n
11
22

hzmct@U-64:/study/linuxtest/day03$ sort<1.txt>name.txt
hzmct@U-64:/study/linuxtest/day03$ cat name.txt 

11
11\n22\n
22
/study/linuxtest/day03


==重定向標準錯誤

//grep命令在name.txt中搜索11字符串,若出錯,則將錯誤信息輸入到/dev/null中。下面例子沒有錯誤信息,正確的信息輸出到屏幕
$ grep "11" name.txt 2>/dev/null
11
11\n22\n

~結合使用標準輸出和標準錯誤
//正確信息輸入到right.txt中 錯誤信息輸入到err.txt中
hzmct@U-64:/study/linuxtest/day03$ cd kk 1>right.txt 2>err.txt
hzmct@U-64:/study/linuxtest/day03$ cat err.txt 
-bash: cd: kk: No such file or directory
hzmct@U-64:/study/linuxtest/day03$

~合併標準輸出和標準錯誤
//將正確的信息和錯誤的信息都定向到同一個文件中
$ grep "hello" hello.txt>grep.out 2>&1
$ cat grep.out 
grep: hello.txt: No such file or directory

exec和文件描述符在一起 (重點)

1、  exec命令可以用來代替當前shell;換句話說,並沒有啓動子shell,使用
這一命令時,任何現有環境都將被清除,並重新啓動一個shell。
exec command        command通常是一個shell腳本。
Eg:測試執行完該命令後,需要重新登錄shell,然後export聲明的變量都失效了。exec ./hello.sh

//例子  執行完命令後,卻退出了。。。。
hzmct@U-64:/study/linuxtest/day03$ exec ls
1.sh   1weizhi.sh  3echo.sh  err.txt  grep.out  right.txt  tee.log  testdir.sh
1.txt  2find.sh    4read.sh  exec.sh  name.txt  sort.out   testdir1.sh

Connection closed by foreign host.

Disconnected from remote host(u1) at 10:00:29.

Type `help' to learn how to use Xshell prompt.
[c:\~]$ 
Reconnecting in 30 seconds. Press any key to exit local shell.
......



2、對文件描述符進行操作時,也只有這麼使用,它不會覆蓋你的當前的shell

//例子
#!/bin/bash
#把0號文件描述符的東西賦值給3號文件描述符 把name.txt的東西
#賦給0號文件描述符,即name.txt作爲標準輸入了
exec 3<&0 0<name.txt
read line1
read line2
#使用完要還原,將3號文件描述符賦給0號文件描述符
exec 0<&3
echo $line1
echo $line2

//查看name.txt的內容
hzmct@U-64:/study/linuxtest/day03$ cat name.txt 
11
22
33
hzmct@U-64:/study/linuxtest/day03$ ./5exec.sh 
11
22


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