版本記錄
| 版本號 | 時(shí)間 |
|---|---|
| V1.0 | 2023.07.17 星期一 |
前言
Shell腳本相信大家都用過,Shell 是一個(gè)用 C 語言編寫的程序,它是用戶使用Linux的橋梁。Shell既是一種命令語言,又是一種程序設(shè)計(jì)語言。Shell 腳本(shell script),是一種為 shell 編寫的腳本程序。大家平時(shí)說的和用到的都是指的是shell腳本編程,不是指開發(fā)shell自身。這個(gè)模塊我們就一起來看下shell腳本編程。感興趣的可以看下面幾篇文章。
Shell初體驗(yàn)(一) —— Shell入門(一)
變量
1. 變量的命名
一個(gè)命名的簡單示例
name="dodo"
變量的命名要遵循下面規(guī)則
- 命名只能使用英文字母,數(shù)字和下劃線,首個(gè)字符不能以數(shù)字開頭
- 中間不能有空格,可以使用下劃線 _
- 不能使用標(biāo)點(diǎn)符號
- 不能使用bash里的關(guān)鍵字(可用help命令查看保留關(guān)鍵字)
2. 變量類型
運(yùn)行shell時(shí),會(huì)同時(shí)存在三種變量:
- 局部變量:局部變量在腳本或命令中定義,僅在當(dāng)前shell實(shí)例中有效,其他shell啟動(dòng)的程序不能訪問局部變量。
- 環(huán)境變量:所有的程序,包括shell啟動(dòng)的程序,都能訪問環(huán)境變量,有些程序需要環(huán)境變量來保證其正常運(yùn)行。必要的時(shí)候shell腳本也可以定義環(huán)境變量。
- Shell變量:shell變量是由shell程序設(shè)置的特殊變量。shell變量中有一部分是環(huán)境變量,有一部分是局部變量,這些變量保證了shell的正常運(yùn)行
3. 只讀變量
使用 readonly 命令可以將變量定義為只讀變量,只讀變量的值不能被改變。
先看一個(gè)簡單的示例
#!/bin/bash
host="www.xxx.com"
readonly host
host="www.aaa.com"
下面我們就執(zhí)行這個(gè)腳本,就會(huì)發(fā)現(xiàn)報(bào)錯(cuò)了
./test.sh: line 5: host: readonly variable
報(bào)的是第5行錯(cuò)誤,提示信息是host是只讀變量
4. 刪除變量
使用unset命令可以刪除變量,語法:
unset variable_name
下面是一個(gè)簡單示例
#!/bin/bash
host="www.xxx.com"
unset host
echo $host
我們執(zhí)行這個(gè)腳本./test.sh就會(huì)發(fā)現(xiàn)沒有任何輸出,因?yàn)槭褂胾nset刪除了變量。
5. 變量的使用
變量的使用需要在變量前加上美元符號$,下面就是一個(gè)簡單示例:
#!/bin/bash
host="www.xxx.com"
echo ${host}
或
echo $host
執(zhí)行腳本,都會(huì)有下面輸出:
www.xxx.com
需要說明的是:
{}這個(gè)大括號是非必須的,但是加上是一個(gè)好習(xí)慣。加花括號是為了幫助解釋器識別變量的邊界。
可以看下面這個(gè)示例
#!/bin/bash
host="www.xxx.com"
echo "This is a $hostname"
這里host變量沒有用大括號,解析器就會(huì)把hostname當(dāng)成一個(gè)變量,所以就會(huì)有下面的輸出
This is a
下面我們加上大括號
#!/bin/bash
host="www.xxx.com"
echo "This is a ${host}name"
接著運(yùn)行下腳本
This is a www.xxx.comname
可以看見,host被識別為一個(gè)已定義變量,可以正常的輸出了。
注釋
以 # 開頭的行就是注釋,會(huì)被解釋器忽略。
Shell腳本的注釋可以使用command + /,想去掉注釋同理。
字符串
1. 字符串的表示
字符串是shell編程中最常用最有用的數(shù)據(jù)類型,字符串可以用單引號,也可以用雙引號,也可以不用引號。
單引號
string='abcdefg'
單引號字符串的限制:
- 單引號里的任何字符都會(huì)原樣輸出,單引號字符串中的變量是無效的;
- 單引號字串中不能出現(xiàn)單獨(dú)一個(gè)的單引號(對單引號使用轉(zhuǎn)義符后也不行),但可成對出現(xiàn),作為字符串拼接使用。
雙引號
#!/bin/bash
string="abcdefg"
str="\"$string\"是前7個(gè)字母"
echo $str
//輸出
"abcdefg"是前7個(gè)字母
雙引號的優(yōu)點(diǎn):
- 雙引號里可以有變量
- 雙引號里可以出現(xiàn)轉(zhuǎn)義字符
2. 字符串的長度
語法:字符串的長度使用${#string},string是字符串變量名。
看下面一個(gè)示例
#!/bin/bash
string="abcdefg"
echo ${#string}
//輸出
7
變量為字符串時(shí),${#string} 等價(jià)于 ${#string[0]}:
#!/bin/bash
string="abcdefg"
echo ${#string[0]}
//輸出
7
3. 子字符串
可以通過下面語法獲取字符串中的子字符串
語法:${string:index:length},這里string是字符串變量,index是下角標(biāo),length是要截取的字符串長度。
可以通過下面示例獲取子字符串
#!/bin/bash
string="abcdefg"
echo ${string:0:3}
//輸出
abc
可以看見,輸出從索引0開始的長度為3的子字符串
4. 字符串的拼接
字符串的拼接,可以使用單引號,也可以使用雙引號。
雙引號拼接
#!/bin/bash
name="liLei"
greeting="hello, nice to meet you, ${name}!"
echo $greeting
#!/bin/bash
name="liLei"
greeting="hello, nice to meet you, "$name"!"
echo $greeting
上面?zhèn)z種拼接方式的輸出都是一樣的
hello, nice to meet you, liLei!
單引號拼接
#!/bin/bash
name="liLei"
greeting='hello, nice to meet you, '$name'!'
echo $greeting
hello, nice to meet you, liLei!
再看下面這種形式
#!/bin/bash
name="liLei"
greeting='hello, nice to meet you, ${name}!'
echo $greeting
hello, nice to meet you, ${name}!
后面這種樣式,可以說明單引號里這么引用變量是無效的,會(huì)被當(dāng)成字符串,原樣輸出。
5. 查找字符中字符的位置
expr index方法
語法:expr index string1 string2,在string1中找到string2的位置。
我們看下下面簡單示例:
#!/bin/bash
string="hello world"
result=`expr index "$string" ll`
echo $result
我們運(yùn)行腳本會(huì)發(fā)現(xiàn)報(bào)錯(cuò)了
expr: syntax error
這個(gè)提示很好理解,提示意思就是expr有語法錯(cuò)誤,但是仔細(xì)檢查了好幾遍并沒發(fā)現(xiàn)有什么錯(cuò)誤。接著我們在終端運(yùn)行下面命令。
man expr
可以看見一個(gè)命令的使用說明,往下拉可以看見下面提示:
STANDARDS
The expr utility conforms to IEEE Std 1003.1-2008 (“POSIX.1”).
The extended arithmetic range and overflow checks do not conflict with POSIX's requirement that arithmetic be done using signed longs, since they
only make a difference to the result in cases where using signed longs would give undefined behavior.
According to the POSIX standard, the use of string arguments length, substr, index, or match produces undefined results. In this version of expr,
these arguments are treated just as their respective string values.
HISTORY
An expr utility first appeared in the Programmer's Workbench (PWB/UNIX). A public domain version of expr written by Pace Willisson <pace@blitz.com>
appeared in 386BSD-0.1.
意思就是
根據(jù)POSIX標(biāo)準(zhǔn),使用字符串參數(shù)length,substr,index或match會(huì)產(chǎn)生不確定的結(jié)果。
在此版本的expr中,這些參數(shù)被視為它們各自的字符串值。也就是沒有這些方法。
繼續(xù)查了下資料
bash: "expr index string1 string2" gives "syntax error"
In a bash script, I was trying to use the command
expr index string1 string2
to find the position of string2 in string1, but this does not work on OS X while it works ok on several Linux machines. Reading the man page, I realized expr does something quite different on OS X than on Linux.
https://discussions.apple.com/thread/923299
The expr in Linux is generally GNU expr. Mac OS X uses BSD expr which does not have the index command.
那說明這個(gè)index方法在Mac OS上已經(jīng)不能用了。大家有別的系統(tǒng)的可以在自己機(jī)器上嘗試下,我就不給大家試了。
awk
我們可以使用awk去匹配,看下面這個(gè)示例
#!/bin/bash
echo "This is a test" | awk '{printf("%d\n", match($0, "is"))}'
這個(gè)示例很清晰,就是找字符串"This is a test"中"is"的索引,這里可以看見"is"出現(xiàn)了2次,我們運(yùn)行下,如下輸出:
3
可以看見是找到了,并且索引為3,也就是找到的是"This"中的"is",是符合預(yù)期的,且索引是從1開始的。所以:
- 這里是求子字符串所在的第一個(gè)符合條件的索引
- 找到則返回指定的正值,找不到符合的則返回0
- 如果可以找到,那索引是從1開始的
后記
本文講述了Shell中的變量和字符串,感興趣的給個(gè)贊或者關(guān)注,有問題的話,歡迎批評留言指正。
