很多人误以为shell脚本只能在命令行下使用。其实shell也可以调用一些GUI组件,例如菜单,警告框,进度条等等。你可以控制最终的输出,光标位置还有各种输出效果。下面我将介绍一些工具,帮助你创建强大的,互动的,用户友好的 Unix/Linux shell脚本。我在FreeBSD和Linux下测试过这些工具,不过其他UNIX系列的操作系统应该都支持的。
- notify-send 命令
这个命令可以让你通过通知进程发送一个桌面通知给用户。这可以用来向用户发送提示,或者显示一些信息而不用打断用户工作。你需要安装如下软件包:
1
2
3
4
5
6
7
8
9
10 1
2
3
4
5 $ sudo apt-get install libnotify-bin
6
7
8
9
10
下面这个例子展示了如何从命令行向桌面发送一个简单的消息:
1
2
3
4
5
6
7
8
9
10 1
2
3
4
5 notify-send "rsnapshot done :)"
6
7
8
9
10
输出:
下面是一个复杂一点的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 1
2
3
4
5 ....
6
7 alert=18000
8
9 live=$(lynx --dump http://money.rediff.com/ | grep 'BSE LIVE' | awk '{ print $5}' | sed 's/,//g;s/\.[0-9]*//g')
10
11 [ $notify_counter -eq 0 ] && [ $live -ge $alert ] && { notify-send -t 5000 -u low -i "BSE Sensex touched 18k"; notify_counter=1; }
12
13 ...
14
15
16
输出:
这里的参数解释如下:
- -t 5000:指定超时的时间,毫秒
- -u low:设置是否紧急
- -i gtk-dialog-info:通知图标,你可以指定图标 -i /path/to/your-icon.png
- tput 命令
这个命令是用来设置终端特性的:
- 移动光标
- 获得终端信息
- 设置前景和背景色
- 设置粗体模式
- 设置反模式等等
举例:
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162 1
2
3
4
5 01 #!/bin/bash
6
7
8
9 02
10
11
12
13 03 # clear the screen
14
15
16
17 04 tput clear
18
19
20
21 05
22
23
24
25 06 # Move cursor to screen location X,Y (top left is 0,0)
26
27
28
29 07 tput cup 3 15
30
31
32
33 08
34
35
36
37 09 # Set a foreground colour using ANSI escape
38
39
40
41 10 tput setaf 3
42
43
44
45 11 echo "XYX Corp LTD."
46
47
48
49 12 tput sgr0
50
51
52
53 13
54
55
56
57 14 tput cup 5 17
58
59
60
61 15 # Set reverse video mode
62
63
64
65 16 tput rev
66
67
68
69 17 echo "M A I N - M E N U"
70
71
72
73 18 tput sgr0
74
75
76
77 19
78
79
80
81 20 tput cup 7 15
82
83
84
85 21 echo "1. User Management"
86
87
88
89 22
90
91
92
93 23 tput cup 8 15
94
95
96
97 24 echo "2. Service Management"
98
99
100
101 25
102
103
104
105 26 tput cup 9 15
106
107
108
109 27 echo "3. Process Management"
110
111
112
113 28
114
115
116
117 29 tput cup 10 15
118
119
120
121 30 echo "4. Backup"
122
123
124
125 31
126
127
128
129 32 # Set bold mode
130
131
132
133 33 tput bold
134
135
136
137 34 tput cup 12 15
138
139
140
141 35 read -p "Enter your choice [1-4] " choice
142
143
144
145 36
146
147
148
149 37 tput clear
150
151
152
153 38 tput sgr0
154
155
156
157 39 tput rc
158
159
160
161
162
输出:
- setleds 命令
这个命令可以让你控制键盘灯,例如打开数字键盘灯:
1
2
3
4
5
6
7
8
9
10 1
2
3
4
5 setleds -D +num
6
7
8
9
10
关闭数字键盘灯:
1
2
3
4
5
6
7
8
9
10 1
2
3
4
5 setleds -D -num
6
7
8
9
10
-caps: 清除大写灯
- +caps:打开大写灯
- -scroll:清除滚动锁
- +scroll:打开滚动锁
- zenity 命令
这个命令可以显示GTK+的对话框,然后返回用户的输入。你可以用这个命令在脚本中显示信息,并要求用户输入信息。下面这段代码就是域名的whois查询:
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102 1
2
3
4
5 01 #!/bin/bash
6
7
8
9 02 # Get domain name
10
11
12
13 03 _zenity="/usr/bin/zenity"
14
15
16
17 04 _out="/tmp/whois.output.$$"
18
19
20
21 05 domain=$(${_zenity} --title "Enter domain" \
22
23
24
25 06 --entry --text "Enter the domain you would like to see whois info" )
26
27
28
29 07
30
31
32
33 08 if [ $? -eq 0 ]
34
35
36
37 09 then
38
39
40
41 10 # Display a progress dialog while searching whois database
42
43
44
45 11 whois $domain | tee >(${_zenity} --width=200 --height=100 \
46
47
48
49 12 --title="whois" --progress \
50
51
52
53 13 --pulsate --text="Searching domain info..." \
54
55
56
57 14 --auto-kill --auto-close \
58
59
60
61 15 --percentage=10) >${_out}
62
63
64
65 16
66
67
68
69 17 # Display back output
70
71
72
73 18 ${_zenity} --width=800 --height=600 \
74
75
76
77 19 --title "Whois info for $domain" \
78
79
80
81 20 --text-info --filename="${_out}"
82
83
84
85 21 else
86
87
88
89 22 ${_zenity} --error \
90
91
92
93 23 --text="No input provided"
94
95
96
97 24 fi
98
99
100
101
102
输出:
- kdialog 命令
这个命令和zenity很想,只不过它是为KDE/QT应用准备的。使用方法如下:
1
2
3
4
5
6
7
8
9
10 1
2
3
4
5 kdialog --dontagain myscript:nofilemsg --msgbox "File: '~/.backup/config' not found."
6
7
8
9
10
输出
你可以查看 shell scription with KDE Dialogs 来获取更多信息
- Dialog
这个命令可以在shell脚本中显示文本组件。它使用了curses和ncurses类库。示例代码:
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 1
2
3
4
5 01 >#!/bin/bash
6
7
8
9 02 dialog --title "Delete file" \
10
11
12
13 03 --backtitle "Linux Shell Script Tutorial Example" \
14
15
16
17 04 --yesno "Are you sure you want to permanently delete \"/tmp/foo.txt\"?" 7 60
18
19
20
21 05
22
23
24
25 06 # Get exit status
26
27
28
29 07 # 0 means user hit [yes] button.
30
31
32
33 08 # 1 means user hit [no] button.
34
35
36
37 09 # 255 means user hit [Esc] key.
38
39
40
41 10 response=$?
42
43
44
45 11 case $response in
46
47
48
49 12 0) echo "File deleted.";;
50
51
52
53 13 1) echo "File not deleted.";;
54
55
56
57 14 255) echo "[ESC] key pressed.";;
58
59
60
61 15 esac
62
63
64
65
66
- logger 命令
这个命令可以让你写入系统日志例如 /var/log/messages:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 1
2
3
4
5 1 logger "MySQL database backup failed."
6
7
8
9 2 tail -f /var/log/messages
10
11
12
13 3 logger -t mysqld -p daemon.error "Database Server failed"
14
15
16
17 4 tail -f /var/log/syslog
18
19
20
21
22
输出:
1
2
3
4
5
6
7
8
9
10 1
2
3
4
5 Apr 20 00:11:45 vivek-desktop kernel: [38600.515354] CPU0: Temperature/speed normal
6
7 Apr 20 00:12:20 vivek-desktop mysqld: Database Server failed
8
9
10
- setterm 命令
这个命令可以设置中断的属性。下面的例子是强制屏幕全黑15分钟,并且60分钟后把显示器设为待机状态:
1
2
3
4
5
6
7
8
9
10 1
2
3
4
5 setterm -blank 15 -powersave powerdown -powerdown 60
6
7
8
9
10
下面这段命令可以在中断显示加下划线的文字:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 1
2
3
4
5 setterm -underline on;
6
7
8
9 echo "Add Your Important Message Here"
10
11
12
13 setterm -underline off
14
15
16
17
18
或者你可以关闭光标:
1
2
3
4
5
6
7
8
9
10 1
2
3
4
5 setterm -cursor off
6
7
8
9
10
- smbclient:向 MS-Windows 系统发送消息
smbclient可以和 SMB/CIFS服务器通信。它可以向MS-Windows系统的指定用户发送消息:
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 1
2
3
4
5 1 smbclient -M WinXPPro <<EOF
6
7
8
9 2 Message 1
10
11
12
13 3 Message 2
14
15
16
17 4 ...
18
19
20
21 5 ..
22
23
24
25 6 EOF
26
27
28
29
30
或者
1
2
3
4
5
6
7
8
9
10 1
2
3
4
5 1 echo "${Message}" | smbclient -M salesguy2
6
7
8
9
10
- Bash Socket 编程
你可以在bash中开启一个socket链接,并且传输数据。Bash有两个特殊的设备文件:
- /dev/tcp/host/port – 如果hostname,和port是合法的话,bash会尝试开启一个TCP连接。
- /dev/udp/host/port – 如果hostname和port是合法的话,bash会开启一个UDP连接。
你可以利用这个技术来测试一台主机的端口是否是开启的,而不需要使用nmap或者port扫描器:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 1
2
3
4
5 # find out if TCP port 25 open or not
6
7
8
9 (echo >/dev/tcp/localhost/25) &>/dev/null && echo "TCP port 25 open" || echo "TCP port 25 close"
10
11
12
13
14
你可以 使用循环来查找开着的端口:
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 1
2
3
4
5 1 echo "Scanning TCP ports..."
6
7
8
9 2 for p in {1..1023}
10
11
12
13 3 do
14
15
16
17 4 (echo >/dev/tcp/localhost/$p) >/dev/null 2>&1 && echo "$p open"
18
19
20
21 5 done
22
23
24
25
26
输出:
Scanning TCP ports…
22 open
53 open
80 open
139 open
445 open
631 open
下面的这个例子让你的脚本扮演HTTP客户端:
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 1
2
3
4
5 01 #!/bin/bash
6
7
8
9 02 exec 3<> /dev/tcp/${1:-www.cyberciti.biz}/80
10
11
12
13 03
14
15
16
17 04 printf "GET / HTTP/1.0\r\n" >&3
18
19
20
21 05 printf "Accept: text/html, text/plain\r\n" >&3
22
23
24
25 06 printf "Accept-Language: en\r\n" >&3
26
27
28
29 07 printf "User-Agent: nixCraft_BashScript v.%s\r\n" "${BASH_VERSION}" >&3
30
31
32
33 08 printf "\r\n" >&3
34
35
36
37 09
38
39
40
41 10 while read LINE <&3
42
43
44
45 11 do
46
47
48
49 12 # do something on $LINE
50
51
52
53 13 # or send $LINE to grep or awk for grabbing data
54
55
56
57 14 # or simply display back data with echo command
58
59
60
61 15 echo $LINE
62
63
64
65 16 done
66
67
68
69
70
关于GUITools和Cronjob
如果你使用cronjob来调用你的脚本的话,你要通过“
export DISPLAY=[user's machine]:0 ”命令来设置本地的 display/input 服务。例如调用 /home/vivek/scripts/monitor.stock.sh脚本,它使用了 zenity 工具:
1
2
3
4
5
6
7
8
9
10 1
2
3
4
5 1 @hourly DISPLAY=:0.0 /home/vivek/scripts/monitor.stock.sh
6
7
8
9
10
所有的命令你都可以通过“man”来查询详细的使用方式。