目录

第3章 控制脚本运行

[TOC]

变量

使用变量: $variable${variable}都可以,但是加大括号允许你将变量和其它文字直接连接起来输出,如${filename}xxx

For循环

例1:超级简单的备份脚本(没有考虑是文件还是目录)

1
2
3
4
5
for filename in *
do
	echo "Backing up ${filename}"
	cp $filename $filename.bak
done

例2:for循环的list_of_items可以当场指定

1
2
3
4
for i in 1 2 3 4 5 6 7 8 9; do
	echo -n '$i ' # -n可以防止换行
	sleep 1 #单位:秒
done

特别地,Bash Shell支持类C的for循环

1
2
3
4
5
max=10
for ((i=1; i <= max ; i++))
do
	echo -n “$i...”
done

If语句

1
2
3
4
5
if (condition_command) then
	commands
else
	commands
fi

例1:检查命令是否运行成功

  • Unix命令返回0代表成功,失败一般返回负数,但也有正数。返回的命令:exit number
  • 另外,Unix带了俩程序,truefalse,它们永远返回true/false
1
2
3
4
5
if (sh some_script.sh) then
	echo 'success'
else
	echo 'failure'
fi

例1改进版:重定向

1
2
3
4
5
if (ls > /dev/null) then #不然会先得到一系列ls的输出再得到下面的两个echo之一,看上去不舒服
	echo “ls is true”
else
	echo “ls is false”
fi

重定向的三个选项

  • 0是stdin,1是stdout,2是stderr>默认是1,如需重定向标准错误,需2>

  • 例2:检测机器上存在哪些*sh巧妙的例子

    • bash -c ls-c选项是从命令行接受指令运行
1
2
3
4
5
6
7
8
for check_v in sh bash zsh csh ash; do
	cmd="check_v -c exit"
	if ($cmd > /dev/null 2> /dev/null) then
		echo 'This machine has ${check_v}'
	else
		echo '${check_v} NOT found'
	fi
done

例3:elif

Test语句

if语句的条件必须去执行一条指令,而对于比较变量,我们更倾向于用test语句,它可以比较变量,检查文件权限,甚至查找文件是否存在,一般是一个built-in命令。结合if用!

注意,返回0是true

比较数字

  • Test Usage
    $x -eq $y 如果x == y,返回true
    $x -ne $y 如果x != y,返回true
    $x -ge $y 如果x >= y,返回true
    $x -lt $y 如果x < y,返回true

比较字符串

  • Test Usage
    “$s1” = “$s2” Returns true if s1 equals s2
    “$s1” != “$s2” Returns true if s1 does not equal s2
    $s1 Returns true if s1 is not null
    $s1 -z Returns true if the length of s1 (the number of char-
    acters in s1) is zero
  • 可以test未经赋值过的变量,不会报错,会认为它是null

测试文件

  • test -d,测试是否是目录

  • test -e,测试是否存在

逻辑运算

神奇的东东

[是一个built-in指令,而]是它的参数,[就是test的功能,即

1
2
3
4
if [test_options]
then
else
fi

注意,上面省略了if的括号,then必须换行,如果不省略的话可以不换行

1
2
if ([test_options]) then
fi

Case语句

TODO,原书P145

感觉语法有点奇怪

While语句

1
2
3
4
while [ test_condition ]
do
	commands
done

实例1

mousewheel脚本

  • Ubuntu浏览器中鼠标滚轮太慢了,于是用了大佬写的脚本提升滚轮速度(基本原理是利用X Windows中的鼠标解析器imwheel,它会读取~/.imwheelrc配置,只需生成这个配置即可)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#!/bin/bash
# Version 0.1 Tuesday, 07 May 2013
# Comments and complaints http://www.nicknorton.net
# GUI for mouse wheel speed using imwheel in Gnome
# imwheel needs to be installed for this script to work
# sudo apt-get install imwheel
# Pretty much hard wired to only use a mouse with
# left, right and wheel in the middle.
# If you have a mouse with complications or special needs,
# use the command xev to find what your wheel does.
#
### see if imwheel config exists, if not create it ###
if [ ! -f ~/.imwheelrc ]
then

    cat >~/.imwheelrc<<EOF
    ".*"
    None,      Up,   Button4, 1
    None,      Down, Button5, 1
    Control_L, Up,   Control_L|Button4
    Control_L, Down, Control_L|Button5
    Shift_L,   Up,   Shift_L|Button4
    Shift_L,   Down, Shift_L|Button5
    None,  Thumb1,  Alt_L|Left
    None,  Thumb2,  Alt_L|Right
    EOF

fi
##########################################################

CURRENT_VALUE=$(awk -F 'Button4,' '{print $2}' ~/.imwheelrc)

# NEW_VALUE=$(zenity --scale --window-icon=info --ok-label=Apply --title="Wheelies" --text "Mouse wheel speed:" --min-value=1 --max-value=100 --value="$CURRENT_VALUE" --step 1)
if [ $# -eq 1 ]; then
	NEW_VALUE=$1
else
	NEW_VALUE=$(zenity --scale --window-icon=info --ok-label=Apply --title="Wheelies" --text "Mouse wheel speed:" --min-value=1 --max-value=100 --value="$CURRENT_VALUE" --step 1)
fi

if [ "$NEW_VALUE" == "" ];
then exit 0
fi

sed -i "s/\($TARGET_KEY *Button4, *\).*/\1$NEW_VALUE/" ~/.imwheelrc # find the string Button4, and write new value.
sed -i "s/\($TARGET_KEY *Button5, *\).*/\1$NEW_VALUE/" ~/.imwheelrc # find the string Button5, and write new value.

cat ~/.imwheelrc
imwheel -kill

这个脚本实现的功能就是,如果不存在配置就创建一个;然后读取当前值,读取用户输入并设置为新的当前值。其中用到了判断和awk、sed语句(在第六章会讲到)

因为觉得GUI不太方便,于是加了一个命令行接口,就是34-37行,判断如果有一个命令行参数则直接设为第一个参数(因为只是我自己用就没有加异常输入处理)