0%

bash-shell-ABC

要在服务器进行一些重复性的体力活,干脆简单看了下shell,下面记录一些内容,都是最基本的用法。

``、’’和””(反引号、单引号和双引号)

以输出为例,``内的内容作为一个命令,先执行其中命令,再执行原命令,即代表命令替换;’’内的原原本本的输出;””内的内容,进行参数替换(如$name)和命令替换(如`echo abc`)。

比如下面代码

1
2
echo "`echo hello world`"
echo '`echo hello world`'

输出将是

1
2
hello world
`echo hello world`

定义变量

直接上例子,如:

1
2
a = helloWorld
echo $a

会报错,因为空格被认为是分隔符,定义变量等号两侧不能有空格。如:

1
2
a=hello world
echo $a

会报错,因为“hello world”中间的空格被认为是分隔符。可以使用引号将内容包含起来,比如

1
2
3
4
a=helloworld
b="hello world"
echo $a
echo $b

定义函数

函数要先定义再使用,定义和调用的格式如下:

1
2
3
4
5
function  fun(){
echo "fun print"$1 $2
}

fun hello world

输出

1
fun printhello world

echo 函数会将之后的内容按格式输出。

$1 和 $2 代表传入的第一个参数、第二个参数,以此类推。

if

比如

1
2
3
4
5
s=matian
if [ $s = 'ma' ]
then
echo $s
fi

[] 内表达式两侧要有空格。

= 是比较字符是否相等,两侧要有空格。

另有,运算符

1
2
3
4
5
6
# 
!
#
-o
#
-a

用于一个条件即一个“[]”内的多个条件之间的判断。

运算符

1
2
3
4
# 
||
#
&&

用于多个条件即多个“[]”之间的判断。

即:

1
2
3
4
5
6
7
8
9
if [ condition1 -a condition2 ]
then
#.......
fi

if [ condition1 ] && [ condition2 ]
then
#.......
fi

for

比如

1
2
3
4
for file in `ls ~`
do
echo $file
done

正则表达式

比如

1
2
3
4
5
s=world
if [[ $s =~ w.{3}d ]]
then
echo $s
fi

可以匹配成功,输出

1
world

要注意,if 部分使用的是 “[[]]” 而不是 “[]”,“[[]]” 支持字符串的模式匹配,使用 “=~” 时支持正则表达式。

read 与 echo

read 读取一个输入到指定变量(不指定时,读取到环境变量REPLY)。read 命令指定 -p 参数时,可以输出一个提示。

echo 作为输出,-e 指定输出的内容中转义字符生效(默认不进行转义),-n 指定不换行(echo 函数默认换行)

1
2
3
4
5
6
7
8
9
echo -e "input name:\n"
read name
echo $name

read
echo -n $REPLY

read -p "input host:" host
echo $host

三次输出依次输入”matian”、”reply”和”matian.connorma.cn”,整个过程的输入和输出如下:

1
2
3
4
5
6
7
input name:

matian
matian
reply
replyinput host:matian.connorma.cn
matian.connorma.cn

sed 命令

使用 sed 命令进行文本编辑,如使用 s 命令进行正则匹配和文本替换:

1
2
3
sed 's/regexp/replacement/flags'

sed "s/regexp/replacement/flags"

双引号的单引号的区别与上文相同,需要传入变量时使用双引号。

假设有如下文件 test.xml:

1
2
3
4
5
<load module="mod_h26x"/>
<param name="listen-ip" value="0.0.0.0"/>
<condition field="$default_username" expression="test" break="never">
<param name="listen-ip2" value="0.0.0.0"/>
<condition field="${default_password}" expression="1234" break="never">

要将 listen-ip 的 value 修改为 127.0.0.1,可以使用 sed 命令进行文本替换,如下(注意双引号最后部分,没有传入 flags 时,最后仍然有一个 “/”):

1
sed -i "s/<param name=\"listen-ip\".*/<param name=\"listen-ip\" value=\"127.0.0.1\"\/>/" "test.xml"

修改后的 test.xml 变为:

1
2
3
4
5
<load module="mod_h26x"/>
<param name="listen-ip" value="127.0.0.1"/>
<condition field="$default_username" expression="test" break="never">
<param name="listen-ip2" value="0.0.0.0"/>
<condition field="$default_password" expression="1234" break="never">

要注意,使用双引号时,内部的特殊字符需要转义,同时可以传入变量。如以下命令,匹配“$default_password”时需要对“$”进行转义,$password 作为变量传入

1
2
password=$1
sed -i "s/<condition field=\"\$default_password\".*/<condition field=\"\$default_password\" expression=\"$password\" break="never"\/>/" "test.xml"

调用以上脚本并传入参入“123456”,执行后 test.xml 变为

1
2
3
4
5
<load module="mod_h26x"/>
<param name="listen-ip" value="127.0.0.1"/>
<condition field="$default_username" expression="test" break="never">
<param name="listen-ip2" value="0.0.0.0"/>
<condition field="$default_password" expression="123456" break=never/>