Shell日常使用的小技巧
Shell 腳本在我們?nèi)粘i_發(fā)和學習都有舉足輕重的地位,比如看一些開源項目,比如項目中的各式各樣的腳本,對于促進生產(chǎn)力工具有很大幫助!
1、命令小技巧
1、-x命令進行跟蹤調(diào)試執(zhí)行
- #!/bin/sh
- num1=10
- num2=20
- if (($num1 <= $num2)); then
- echo num1 lesser equal num2
- else
- echo num1 greater num2
- fi
執(zhí)行:
- ➜ note git:(master) ✗ sh -x /Users/fanhaodong/Desktop/project/test.sh
- + num1=10
- + num2=20
- + (( 10 <= 20 ))
- + echo num1 lesser equal num2
- num1 lesser equal num2
2、-c命令 (執(zhí)行命令參數(shù))
- ➜ note git:(master) ✗ sh -c << EOF "
- dquote> echo hello world
- dquote> echo hello world2
- dquote> "
- heredoc> EOF
- hello world
- hello world2
3、使用set變量
- #!/bin/sh
- # -v Print shell input lines as they are read.
- # -x Print commands and their arguments as they are executed.
- # -e Exit immediately if a command exits with a non-zero status.
- set -ex
- echo "hello world"
- exit 1
執(zhí)行
- ➜ makefile git:(master) ✗ sh ./main.sh
- + echo 'hello world'
- hello world
- + exit 1
- ➜ makefile git:(master) ✗ echo $?
- 1
幫助可以看:sh -c "help set"
2、語法小技巧
1、${}和$適用場景
1)$ 可能有語法歧義,所以一般使用${}
- #!/bin/sh
- s="my name is s"
- echo 輸出: $sa
- echo 輸出: ${s}a
- #輸出:
- #輸出: my name is sa
2、((cmd))
- 可以替換[-le ] 命令
- num1=10
- num2=20
- if (($num1 <= $num2)); then
- echo num1 lesser equal num2
- fi
3、cat[>>|>][file]<
如果重定向的操作符是<<-,那么分界符(EOF)所在行的開頭部分的制表符(Tab)都將被去除。這可以解決由于腳本中的自然縮進產(chǎn)生的制表符。
- ➜ test cat > glide.yaml << EOF
- heredoc> name: tom
- heredoc> age: 10
- heredoc> hobby:
- heredoc> - football
- heredoc> EOF
- ➜ test cat glide.yaml
- name: tom
- age: 10
- hobby:
- - football
4、 單引號,雙引號,沒有引號的區(qū)別
- #!/bin/sh
- name="tom"
- f1(){
- echo "f1 hello world
- my name is $name
- "
- }
- f2(){
- echo 'f2 hello world
- my name is $name
- '
- }
- f3(){
- echo f3 hello world
- my name is $name
- }
- f1
- f2
- f3
輸出
- ➜ makefile git:(master) ✗ sh ./main.sh
- f1 hello world
- my name is tom
- f2 hello world
- my name is $name
- f3 hello world
- ./main.sh: line 19: my: command not found
可以看到
- 雙引號會自動對變量賦值
- 單引號不會對變量進行賦值等操作
- 不加引號對于換行等功能無法實現(xiàn)!只能使用換行符
- f3(){
- echo f3 hello world \
- my name is $name
- }
5、特殊變量
- $0: 當前腳本的文件名
- $n : 傳遞給腳本或函數(shù)的參數(shù)。n 是一個數(shù)字,表示第幾個參數(shù)。例如,第一個參數(shù)是$1,第二個參數(shù)是$2。
- $#: 傳遞給腳本或函數(shù)的參數(shù)個數(shù)。
- $*: 傳遞給腳本或函數(shù)的所有參數(shù)。
- $@: 傳遞給腳本或函數(shù)的所有參數(shù)(推薦使用這個),當使用"" 雙引號引用是$*會變成字符串而不是數(shù)組
- $?: 上個命令的退出狀態(tài),或函數(shù)的返回值。一般情況下,大部分命令執(zhí)行成功后會返回 0,失敗返回 1。
- $$: 當前Shell進程ID。對于 Shell 腳本,就是這些腳本所在的進程ID。
6、[[]]和[]標準 以及基本語法規(guī)范
具體規(guī)范:
- #!/bin/sh
- name=""
- if [[ -z $name ]]; then
- echo "is zero"
- fi
執(zhí)行后發(fā)現(xiàn)
7、/bin/sh 與 /bin/bash 的區(qū)別
/bin/sh 與 /bin/bash 的區(qū)別
3、獲取命令結(jié)果$(cmd)
有兩種寫法,一種是$()這個并不是所有的shell都支持,但是比較直觀, 另外一種是"``" (它可是適用更多的平臺)
- #!/bin/sh
- echo `ls -a /Users/fanhaodong/note`
- echo $(ls -a /Users/fanhaodong/note)
輸出:
- . .. .DS_Store 1714.jpg docker-rocketmq-cluster gridea-home hexo-home note pdf vuepress-starter
- . .. .DS_Store 1714.jpg docker-rocketmq-cluster gridea-home hexo-home note pdf vuepress-starter
4、輸入輸出重定向2>&1
使用
程序中經(jīng)常有,標準輸出,但是還有錯誤輸出,因此需要合并到一個流中
其實Go的程序中正執(zhí)行腳本的時候可以指定,標準輸出和錯誤輸出
- command := exec.Command(shell, "-c", cmd)
- command.Stdout = os.Stdout
- command.Stderr = os.Stderr
使用的時候:
- 默認為標準輸出重定向,與 1> 相同
- 2>&1 意思是把 標準錯誤輸出 重定向到 標準輸出.
- &>file 意思是把標準輸出和標準錯誤輸出 都重定向到文件file中
例如:
- command >out.file 2>&1&
command >out.file是將command的標準輸出重定向到out.file文件,即輸出內(nèi)容不打印到屏幕上,而是輸出到out.file文件中。2>&1 是將標準出錯重定向到標準輸出,這里的標準輸出已經(jīng)重定向到了out.file文件,即將標準出錯也輸出到out.file文件中。最后一個&,是讓該命令在后臺執(zhí)行。
5、If語句
if 其實就是test 命令
1、格式
1) 換行寫
- if [ condition ]; then
- # body
- elif [ condition ]; then
- # body
- else
- # body
- fi
2)非換行寫
- if [ -f "/Users/fanhaodong/note/note/Makefile1" ]; then echo 111 ; echo 222 ;elif [ -f "/Users/fanhaodong/note/note/README.md" ]; then echo 333 ; echo 4444 ; else echo 555 ; echo 666 ; fi
2、結(jié)果獲取/判斷
結(jié)果輸出0 ,表示為真,可以通過$? 來獲取結(jié)果
3、例如調(diào)試條件
- ➜ note git:(master) ✗ test "abc"!="def"
- ➜ note git:(master) ✗ echo $?
- 0
4、測試文件是否存在
- 如果你要判斷一個文件是否存在,只需要-e 即可,輸出0 表示文件存在 (不在判斷類型的時候推薦使用這個)
- 如果你要判斷一個文件是否為文件夾,并且判斷是否存在,只需要-d 即可
- 如果你要判斷一個文件是否為常規(guī)文件 ,并且判斷是否存在,只需要-f 即可
- -L filename 如果 filename為符號鏈接,則為真
- [root@019066c0cd63 ~]# ls -al
- lrwxrwxrwx 1 root root 5 Mar 1 09:49 c.txt -> a.txt
- [root@019066c0cd63 ~]# [ -L "./c.txt" ]
- [root@019066c0cd63 ~]# echo $?
- 0
- -r filename 如果 filename可讀,則為真
- -w filename 如果 filename可寫,則為真
- -x filename 如果 filename可執(zhí)行,則為真
- -s filename 如果文件長度不為0,則為真
- -h filename 如果文件是軟鏈接,則為真
- ➜ note git:(master) ✗ [ -f "/Users/fanhaodong/note/note/Makefile" ]
- ➜ note git:(master) ✗ echo $?
- 0
- ➜ note git:(master) ✗ [ -f "/Users/fanhaodong/note/note/Makefile1" ]
- ➜ note git:(master) ✗ echo $?
- 1
5、字符串操作
字符串推薦加"" 進行定義
1) 判斷字符串是否為空-z (zero)么
- #!/bin/sh
- str=""
- if [ -z "${str}" ]; then
- echo str is empty
- fi
- # str is empty
2)判斷兩個字符串是否相同
- #!/bin/sh
- str1="str"
- str2="str2"
- if [ "$str1" = "$str2" ]; then
- echo str1 is equal str2
- else
- echo str1 is not equal str2
- fi
- # str1 is not equal str2
4、測試一個命令是否存在command -v $#
- #!/bin/sh
- cmd=go
- if [ `command -v $cmd` ]; then
- echo $cmd command is exists
- else
- echo $cmd command not exists
- fi
- # go command is exists
5、獲取字符串長度${#var}
- #!/bin/sh
- str="hello "
- str1=hello
- echo str 的長度是 ${#str}
- echo str1 的長度是 ${#str1}
- #str 的長度是 8
- #str1 的長度是 5
6、數(shù)字比較
- -eq 等于
- -ne 不等于
- -gt 大于
- -ge 大于等于
- -lt 小于
- -le 小于等于
- #!/bin/sh
- num1=10
- num2=20
- if (($num1 <= $num2)); then
- echo num1 lesser equal num2
- fi
- if [ $num1 -le $num2 ]; then
- echo num1 lesser equal num2
- fi
- # num1 lesser equal num2
- # num1 lesser equal num2
7、shell腳本中if判斷'-a' - '-z'含義
6、for循環(huán)
1、forin; do;;done
- #!/bin/bash
- for item in {1..5}; do echo "$item"; done
- [Running] /bin/bash "/Users/fanhaodong/note/note/Linux/shell/file.sh"
- 1
- 2
- 3
- 4
- 5
2、for((x=0; x<10; x++));do;; done
- for((x=0; x<10; x++));do echo "$x" ;done
7、awk
1、例子
demo
- [root@19096dee708b data]# cat demo.txt
- 11 22
- 111
- 22 33
腳本
- [root@19096dee708b data]# awk -F ':' 'BEGIN {print "start"} /:/ {printf "do1 $1=%s $2=%s\n",$1,$2} {print "do2 .."} END {print "e nd"}' demo.txt
- start
- do1 $1=11 $2=22
- do2 ..
- do2 ..
- do1 $1=22 $2=33
- do2 ..
- e nd
2、格式
- awk -arg1 x1 -arg2 x2 'BEGIN {開始執(zhí)行腳本} 條件 {過程1} {過程2} END{循環(huán)體執(zhí)行完后最后執(zhí)行}'
- 其中條件執(zhí)行正則表達式、判斷等
- 還支持一些內(nèi)置函數(shù) , 一些內(nèi)置變量!
- 過程中支持if函數(shù)
8、sed
首先gun的sed函數(shù)和mac的set是有些不同的!具體看:
- https://superuser.com/questions/307165/newlines-in-sed-on-mac-os-x
具體寫在其他文檔上,目前使用的多個命令也未分享!