Linux shell命令特殊符號


原帖地址: http://www.2cto.com/os/201112/113097.html
       http://www.2cto.com/os/201305/209678.html

1.簡述

( > ) 重定向輸出符號

用法:命令>文件名

特性:覆蓋(當輸入文件和輸出文件是同一文件,文件內容被清空;不適合連續重定向)

典型應用:

~$ cat a b >c  (合並文件)

~$ echo "hello world" > hello.txt  (輸入內容到指定文件)

~$ ./test.sh > /dev/null (刪除程序輸入)

( >> ) 輸出重定向

用法:命令>>文件名

特性:追加

典型應用:

~$ cat hello.txt >> hello2.txt

~$ ./test.sh >> test.echo

( 2> ) 錯誤重定向

用法:命令2>文件名

特性:覆蓋

典型應用:

~$ ./test.sh >> test.error

( 2>> ) 錯誤重定向輸出符號

用法:命令2>>文件名

特性:錯誤信息的追加

典型應用:

~$ ./test.sh 2>>  test.error

( | ) 管道符號

用法:命令1 | 命令2

特性:上一個的命令輸出作為下一個命令的輸入

典型應用:

~$ ps -ef | grep root

( * ) 匹配任意字符

( ? ) 匹配任意一個字符

( & ) 后台運行命令(守護程序)

用法:命令1 &

特性:關閉當前終端窗口,程序仍在運行

典型應用:

~$ ./test.sh &

( && ) 連接多條命令

用法:命令1 && 命令2

特性:如果命令1執行成功,繼續執行命令2;否則,不執行命令2.

典型應用:

~$ apt-get update && apt-get dist-upgrade

( || ) 邏輯或

用法:命令1 || 命令2

特性:如果命令1執行成功,不執行命令2;否則,才執行命令2.

( !) 邏輯非

特性:排除指定范圍.

( [x-y] ) 指定范圍

( # ) 注釋

( "" ) 雙引號

特性:把它所包含的內容作為普通字符,但'' \ $ ``除外.

( '' ) 單引號

特性:把它所包含的內容作為普通字符,無例外.

( `` ) 倒引號

特性:執行它所包含的內容

( \ ) 轉義字符

用法; \符號

特性:把符號的特定含義去掉,使其變成普通標點.

( $ ) 變量調用符號

用法:$變量

特性:調用變量,從而得到‘變量的值

( ; ) 命令分隔符

用法:命令1 ; 命令2

特性:一行語句中,順次執行各命令

( () ) 整體執行

( {} ) 變量分離  


2.詳述

LINUX Shell特殊字符的表示方法
 
# 注釋
1. 表示注釋 #注釋
2. 在引號中間和\#等表示#本身
3.echo ${PATH#*:} # 參數替換,不是一個注釋
4.echo $(( 2#101011 )) # 數制轉換,不是一個注釋
echo "The # here does not begin a comment."
echo 'The # here does not begin a comment.'
echo The \# here does not begin a comment.
echo The # 這里開始一個注釋.
echo ${PATH#*:} # 參數替換, 不是一個注釋.
echo $(( 2#101011 )) # 數制轉換, 不是一個注釋.
這里特別要注意第四個,一定要有空格,否則不認同是注釋
; 分隔
1.命令分隔,在一行中寫多個命令 echo "aa" ; echo "bb"
2.在條件中的if和then如果放在同一行,也用;分隔
 
;; case條件的結束
1.命令分隔,在一行中寫多個命令 echo "aa" ; echo "bb"
2.在條件中的if和then如果放在同一行,也用;分隔
echo hello; echo there
if [ -x "$filename" ]; then    # 注意: "if"和"then"需要分隔. 
echo "File $filename exists."; cp $filename $filename.bak
else
echo "File $filename not found."; touch $filename
fi; echo "File test complete."
 
. 命令相當於
1.命令:source
2.文件名的前綴,隱藏文件
3.目錄:.當前目錄,..父目錄
4.正則表達式:匹配任意單個字符
首先,先舉例說明一下"."作為source使用的實例
#!/bin/bash
. data-file    # 加載一個數據文件.
# 與"source data-file"效果相同, 但是更具可移植性.
# 文件"data-file"必須存在於當前工作目錄, 因為這個文件是使用'basename'來引用的. 
echo "variable1 = $variable1"
echo "variable3 = $variable3"
let "sum = $variable2 + $variable4"
echo "sum = $sum"
exit 0
上面是編寫的include_file腳本,通過 . data-file引入,相當於 c語言中的include data-file,我們看看data-file的內容
# 這是需要被腳本加載的數據文件.
# 這種文件可以包含變量, 函數, 等等.
# 在腳本中可以通過'source'或者'.'命令來加載.                                             
# 讓我們初始化一些變量.
variable1=22
variable2=474
variable3=5
variable4=97
message1="Hello, how are you?"
message2="Enough for now. Goodbye."
接下來我們看看腳本的執行結果:
root@ubuntu:~/resource/study/shell_study# chmod 777 include_file 
root@ubuntu:~/resource/study/shell_study# ls
clear_log  data-file  include_file  show_self
root@ubuntu:~/resource/study/shell_study# ./include_file 
variable1 = 22
variable3 = 5
sum = 571
上面的結果已經很有力的說明了我們想要的結論
.作為隱藏文件時,建立隱藏文件的方法:touch .data-file
 
.作為匹配字符說明如下:ab.  可以表示ab+任意字符,處理換行,並且必須是一個字符ab.不能表示ab
 
"" 部分引用 支持通配符擴展
"STRING"將會阻止(解釋)STRING中大部分特殊的字符
 
' ‘ 全引用,不進行通配符擴展
'STRING'將會阻止STRING中所有特殊字符的解釋. 這是一種比使用"更強烈的形式
 
\ 轉義
\X將會"轉義"字符X. 這等價於"X", 也等價於'X'. \通常用來轉義"和', 這樣雙引號和單引號就不會被解釋成特殊含義了.
 
/ 目錄分隔符
分隔文件名不同的部分(比如 /home/bozo/projects/Makefile).也可以用來作為除法算術操作符.
 
, 多個命令都被執行,但返回最后一個
逗號操作符鏈接了一系列的算術操作. 雖然里邊所有的內容都被運行了,但只有最后一項被返回.
let "t2 = ((a = 9, 15 / 3))" # Set "a = 9" and "t2 = 15 / 3"
逗號之前會運算,但是只有最后一項被返回
 
` 后置引用
`command`結構可以將命令的輸出賦值到一個變量中去. 
cd $LOG_DIR
if [ `pwd` != "$LOG_DIR" ]
then
echo "Can't change to $LOG_DIR"
exit $E_XCD
fi
這里例子是最有力的的說明,在上一章中只不過沒有到這個方法,這里pwd命令會返回當前路徑,然后與LOG_DIR進行比較,同樣你可以定義一個變量保存pwd返回的內容,比如:
path=`pwd`
 
: 操作符
1.空操作,等價於"NOP" (no op, 一個什么也不干的命令). 
  1 :
  2 echo $?   # 0
2.死循環: while :,可以被認為與shell的內建命令,與true作用相同.
 while :
 do
    operation-1
    operation-2
    ...
    operation-n
 done
   
 # 與下邊相同:
 #    while true
 #    do
 #      ...
 #    done
3.在if/then中表示什么都不做,引出分支
if condition
then :   # 什么都不做,引出分支. 
     else
take-some-action
fi
 
4.設置默認參數 : ${username=`whoami`}
: ${username=`whoami`}
# ${username=`whoami`}   如果沒有開頭的":"的話, 將會給出一個錯誤, 除非"username"是一個命令或者內建命令
 
5.變量替換 : ${HOSTNAME?} ${USER?} ${MAIL?}
: ${HOSTNAME?} ${USER?} ${MAIL?}
#  如果一個或多個必要的環境變量沒被設置的話, 就打印錯誤信息. 
 
6.在和 > (重定向操作符)結合使用時,把一個文件截斷到0 長度,沒有修改它的權限;如果文件在之前並不存在,那么就創建它.如: 
: > data.xxx #文件"data.xxx"現在被清空了. 與 cat /dev/null >data.xxx 的作用相同 然而,這不會產生一個新的進程,因為":"是一個內建命令.
在和>>重定向操作符結合使用時,將不會對想要附加的文件產生任何影響.
如果文件不存在,將創建.
7.可能用來作為注釋行, 雖然我們不推薦這么做. 使用#來注釋的話, 將關閉剩余行的錯誤檢查, 所以可以在注釋行中寫任何東西. 然而, 使用:的話將不會這樣.
 : This is a comment that generates an error, ( if [ $x -eq 3] ).
8.":"還用來在/etc/passwd和$PATH變量中做分隔符.
bash$ echo $PATH
/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/sbin:/usr/sbin:/usr/games
 
* 匹配0個或多個字符;數學乘法;**冪運算
root@ubuntu:~/resource/study/shell_study# ls
clear_log  data-file  include_file  show_self
root@ubuntu:~/resource/study/shell_study# echo *
clear_log data-file include_file show_self
 
? 匹配任意一個字符;但在((a>b?a:b))表示c語言中的三目運算
 (( t = a<45?7:11 ))   # C語言風格的三元操作.
 
$ 字符
1.取變量的值 echo $PATH
var1=5
var2=23skidoo
echo $var1     # 5
echo $var2     # 23skidoo
2.正則表達式中表示行的結尾
在正則表達式中, "$"表示行結束符,先分析一下下面的例子吧
root@ubuntu:~/resource/study/shell_study# echo slfjalj$fdjgl
slfjalj
3.${} 參數替換 ${PAHT}
#!/bin/bash
  2 # param-sub.sh
  3 
  4 #  一個變量是否被聲明或設置,
  5 #+ 將會影響這個變量是否使用默認值, 
  6 #+ 即使這個變量值為空(null).
  7 
  8 username0=
  9 echo "username0 has been declared, but is set to null."
 10 echo "username0 = ${username0-`whoami`}"這里定義了username0且初始化是null,所以這里不會有輸出,這里的“-”相當於“=”
 11 # 不會有輸出.
 12 
 13 echo
 14 
 15 echo username1 has not been declared.
 16 echo "username1 = ${username1-`whoami`}"這里username1在上面沒有定義並初始化為null,所以會顯示
 17 # 將會輸出默認值.
 18 
 19 username2=
 20 echo "username2 has been declared, but is set to null."
 21 echo "username2 = ${username2:-`whoami`}"這里上面初始化了username2並初始化為null,但是這里有個“:”
 22 #                            ^
 23 # 會輸出, 因為:-會比-多一個條件測試.
 24 # 可以與上邊的例子比較一下.
 25 
 26 
 27 #
 28 
 29 # 再來一個:
 30 
 31 variable=
 32 # 變量已經被聲明, 但是設為空值. 
 33 
 34 echo "${variable-0}"    # (沒有輸出)
 35 echo "${variable:-1}"   # 1
 36 #               ^
 37 
 38 unset variable
 39 
 40 echo "${variable-2}"    # 2
 41 echo "${variable:-3}"   # 3
 42 
 43 exit 0
我們也看看他的執行結果:
root@ubuntu:~/resource/study/shell_study# chmod 777 para_sub 
root@ubuntu:~/resource/study/shell_study# ls
clear_log  data-file  include_file  para_sub  show_self
root@ubuntu:~/resource/study/shell_study# ./para_sub 
username0 has been declared, but is set to null.
username0 = 
 
username1 has not been declared.
username1 = root
username2 has been declared, but is set to null.
username2 = root ^
 
1
2
3
4.$* 所有參數
5.$# 參數個數
6.$$ 進程的ID
7.$? 進程的返回狀態
 
( )字符
1.命令組,在一個子Shell中運行 (a=3;echo $a) 其中定義的變量在后面不可用
在括號中的變量,由於是在子shell中,所以對於腳本剩下的部分是不可用的. 父進程, 也就是腳本本身, 將不能夠讀取在子進程中創建的變量, 也就是在子shell中創建的變量.
  1 a=123
  2 ( a=321; )       
  3 
  4 echo "a = $a"   # a = 123
  5 # 在圓括號中a變量, 更像是一個局部變量. 
2.數組初始化: array=(a,b,c)
大括號擴展
  1 cat {file1,file2,file3} > combined_file
  2 # 把file1, file2, file3連接在一起, 並且重定向到combined_file中.
  3 
  4 
  5 cp file22.{txt,backup}
  6 # 拷貝"file22.txt"到"file22.b
 
{ } 代碼塊,即一個匿名函數,但其中定義的變量在后面依然可用
#!/bin/bash
# 從/etc/fstab中讀行.
File=/etc/fstab
{
read line1
read line2
read line3
} < $File
 
echo "First line in $File is:"
echo "$line1"
echo
echo "Second line in $File is:"
echo "$line2"
echo
echo "third line in $File is:"
echo "$line3"
exit 0
執行結果:
root@ubuntu:~/resource/study/shell_study# ./test1 
First line in /etc/fstab is:
# /etc/fstab: static file system information.
 
Second line in /etc/fstab is:
#
 
third line in /etc/fstab is:
# Use 'blkid -o value -s UUID' to print the universally unique identifier
接下來看一個例子:
#!/bin/bash
 
echo "Just for a test:"
echo `pwd`
echo "Test end"
} > "test-context"       # 把代碼塊中的所有輸出都重定向到文件中.
 
echo "Results of rpm test in test-context"
exit 0
看看運行結果:
root@ubuntu:~/resource/study/shell_study# chmod 777 test2 
root@ubuntu:~/resource/study/shell_study# ./test2 
Results of rpm test in test-context
root@ubuntu:~/resource/study/shell_study# ls
clear_log  include_file  show_self  test2
data-file  para_sub      test1      test-context
root@ubuntu:~/resource/study/shell_study# cat test-context 
Just for a test:
/root/resource/study/shell_study
Test end
{ } \; 用在find的-exec中 $find -name *.txt -exec cat {} \;
[ ]
1.測試 [-z $1]
2.數組元素 a[1]='test'
3.[[]]表示測試 使用[[ ... ]]條件判斷結構, 而不是[ ... ], 能夠防止腳本中的許多邏輯錯誤. 比如, &&, ||, <, 和> 操作符能夠正常存在於[[ ]]條件判斷結構中, 但是如果出現在[ ]結構中的話, 會報錯.
4.(( ))數學運算
5.在正則表達式中表示范圍 [a-z]
 
< << > 重定向和進程替換 ls -al > a.txt
scriptname >filename 重定向scriptname的輸出到文件filename中. 如果filename存在的話, 那么將會被覆蓋.
command &>filename 重定向command的stdout和stderr到filename中.
command >&2 重定向command的stdout到stderr中.
scriptname >>filename 把scriptname的輸出追加到文件filename中. 如果filename不存在的話, 將會被創建.
[i]<>filename 打開文件filename用來讀寫, 並且分配文件描述符i給這個文件. 如果filename不存在, 這個文件將會被創建.
 
> < 還用在ASCII比較 if [[ "$veg1" < "$veg2" ]]
\<,\> 正則表達式中的單詞邊界.如:bash$grep '\<the\>' textfile
 
| 管道
分析前邊命令的輸出, 並將輸出作為后邊命令的輸入. 這是一種產生命令鏈的好方法.
echo ls -l | sh # 傳遞"echo ls -l"的輸出到shell中,與一個簡單的"ls -l"結果相同.
cat *.lst | sort | uniq # 合並和排序所有的".lst"文件, 然后刪除所有重復的行. 
管道是進程間通訊的一個典型辦法, 將一個進程的stdout放到另一個進程的stdin中. 標准的方法是將一個一般命令的輸出, 比如cat或者echo, 傳遞到一個 "過濾命令"(在這個過濾命令中將處理輸入)中, 然后得到結果.
cat $filename1 $filename2 | grep $search_word
當然輸出的命令也可以傳遞到腳本中.
#!/bin/bash
# uppercase.sh : 修改輸入, 全部轉換為大寫.
tr 'a-z' 'A-Z'
# 字符范圍必須被""引用起來來阻止產生單字符的文件名.
exit 0
現在讓我們輸送ls -l的輸出到一個腳本中.
bash$ ls -l | ./uppercase.sh
-RW-RW-R-- 1 BOZO BOZO 109 APR 7 19:49 1.TXT
-RW-RW-R-- 1 BOZO BOZO 109 APR 14 16:48 2.TXT
-RW-R--R-- 1 BOZO BOZO 725 APR 20 20:56 DATA-FILE
 
管道中的每個進程的stdout比須被下一個進程作為stdin來讀入. 否則, 數據流會阻塞, 並且管道將產生一些非預期的行為.
cat file1 file2 | ls -l | sort# 從"cat file1 file2"中的輸出並沒出現. 
作為子進程的運行的管道, 不能夠改變腳本的變量.
variable="initial_value"
echo "new_value" | read variable
echo "variable = $variable" # variable = initial_value
如果管道中的某個命令產生了一個異常,並中途失敗,那么這個管道將過早的終止. 這種行為被叫做broken pipe, 並且這種狀態下將發送一個SIGPIPE 信號.
 
>| 強制重定向(即使設置了noclobber 選項--就是-C 選項).這將強制的覆蓋一個現存文件.
 
|| 邏輯或操作 ;用在兩個命令之間的時候,表示在前一個命令結束時,若返回值為 false,繼續執行下一個命令
 
&& 邏輯與;用在兩個命令之間的時候,表示在前一個命令結束時,若返回值為 true,繼續執行下一個命令
 
& 后台運行
看一個例子
#!/bin/bash
# background-loop.sh
for i in 1 2 3 4 5 6 7 8 9 10            # 第一個循環.
do
echo
echo -n "$i "
done & # 在后台運行這個循環.
 
# 在第2個循環之后, 將在某些時候執行. 
echo   # 這個'echo'某些時候將不會顯示. 
for i in 11 12 13 14 15 16 17 18 19 20   # 第二個循環.
do
echo -n "$i "
done  
echo   # 這個'echo'某些時候將不會顯示. 
exit 0
看一下結果:
root@ubuntu:~/resource/study/shell_study# ./for_test 
 
11 12 13 14 15 16 17 18 19 20 
root@ubuntu:~/resource/study/shell_study# 
 
-  在所有的命令內如果想使用選項參數的話,前邊都要加上"-".
1.參數選項
2. 減號
3. 重定向stdin和stdout:cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xpvf -)
4.先前的工作目錄 cd -
5.注:使用-開頭的文件名和變量名可能會出現一些問題
 
+ 一個命令或者過濾器的選項標記.
~ home目錄
~+ 當前工作目錄
~- 先前工作目錄
^ 正則表達式中表示行首
$IFS 用來做一些輸入命令的分隔符, 默認情況下是空白
其中命令的很多細節並沒有研究的很徹底,以后見到用到具體的命令再具體分析吧


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM