创建vnc用户🔥
#!/bin/bash
# 用户名,作为一个参数, 必传
userName=$1
# 创建用户时默认家目录
userHomeDefaultParentDir="/home/users/$(date '+%Y%m%d')"
#用户名密码,作为第二个参数
userPasswd=$2
#用户名密码默认值
userPasswdDefault="123456"
#vnc密码,作为第三个参数
vncPasswd=$3
# novnc websockify 代理端口号
noVncPort=$4
# novnc websockify 默认开始最小端口号
noVncDefaultMinPort=8951
# novnc websockify 默认开始最大端口号
noVncDefaultMaxPort=9050
#vnc密码默认值
vncPasswdDefault="123456"
# 内存默认标准最大占比, 作为第四个参数(整数),取值在 0 - 100 之间,不传入默认为70
memUsedPersentStandard=$4
# 内存默认标准最大占比默认值
memUsedPersentStandardDefault=80
# vnc最大用户连接数量。作为第五个参数(整数),不传入默认设置为35
maxVncConnectAmount=$5
# vnc最大用户连接数量默认值
maxVncConnectAmountDefault=35
# 默认的vnc端口从5900开始
vncDefaultPort=5900
# vnc激活的序号 即默认端口号 5900+maxPort
maxPort=1
#要激活的vnc端口
port=5901
# 已存在的vnc配置文件中,配置存放在/etc/tigervnc/vncserver.users中端口序号数组
vncUserPortsArray=()
# vnc开启端口的用户名数组
varActiveUserArray=()
# vnc开启端口的数组
varActivePortArray=()
# vnc用户数组
vncUserArray=()
#vnc当前激活的端口集合
vncActiveArray=()
# 内存使用比例
memUsedPersent=0
#总内存大小
memTotal=0
#已使用内存大小
memUsed=0
# 磁盘路径名
diskUsageNameArray=()
# 磁盘使用占比
diskUsagePrecentArray=()
# 磁盘总大小
diskUsageTotalSizeArray=()
# 磁盘已使用大小
diskUsageUsedSizeArray=()
# 临时变量vi,记录vnc配置文件数组的索引值
vi=0
# vnc用户是否存在,默认不存在 0不存在 1存在
vncUserIsExist=0
# {function} 分割字符串
#传参: 第一个参数:要分割的字符串
splitStringFn() {
#要将$a分割开,先存储旧的分隔符
OLD_IFS="$IFS"
#设置分隔符
IFS=$2
#如下会自动分隔
arr=($1)
#恢复原来的分隔符
IFS="$OLD_IFS"
echo ${arr[*]}
}
# {function} 检查端口是否在使用中,返回值 0未占用 1已被占用
# 传参: 第一个参数:指定的端口号
checkPortIsInUseFn() {
result=1
# var=$(netstat -anp | grep $1)
var=$(lsof -i:$1)
if [[ -z "$var" ]]
then
result=0
fi
return $result
}
# {function} 通过递归的形式
findCanUsePortFn() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:正在检查 $port 是否被占用..."
checkPortIsInUseFn $port
# 判断端口是否被占用
if [[ $? -eq 1 ]]
then
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:发现端口 $port 已被占用,正在尝试重新设立新的接口..."
if [[ $port -ge $noVncDefaultMinPort ]] && [[ $port -le $noVncDefaultMaxPort ]]
then
port=$[$noVncDefaultMaxPort+1]
else
port=$[$port+1]
fi
findCanUsePortFn $port
else
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:端口 $port 尚未占用,可以使用该端口"
fi
}
# {function} 查看用户是否已存在,返回值 0不存在 1已存在
# 传参: 第一个参数:指定的用户名主目录 如/home/users/test
checkUserIsExist() {
result=1
var=$(cat /etc/passwd | grep $1)
if [[ -z "$var" ]]
then
result=0
fi
return $result
}
# {function} 求最大值,返回最大值
# 传参: 第一个参数:整数型数组
maxInArrayFn() {
max=0
for v in $*
do
if [ $max -lt $v ]
then
max=$v
fi
done
echo $max
}
#统计内存使用率
memTotal=`free -h | awk -F '[ :]+' 'NR==2{printf "%s", $2}'`
memUsed=`free -h | awk -F '[ :]+' 'NR==2{printf "%s", $3}'`
memUsedPersent=`free -m | awk -F '[ :]+' 'NR==2{printf "%d", ($3)/$2*100}'`
# 磁盘
eval `df -THP | awk -F '[ ]+' 'NR!=1{printf("diskUsageNameTempArray["NR"]=%s\n"), $1;printf("diskUsageTotalSizeTempArray["NR"]=%s\n"), $3;printf("diskUsageUsedSizeTempArray["NR"]=%s\n"), $4;printf("diskUsagePrecentTempArray["NR"]=%s\n"), $6}'`
# 磁盘路径名
diskUsageNameArrayIndex=0
for item in "${diskUsageNameTempArray[@]}"
do
diskUsageNameArray[diskUsageNameArrayIndex]=${item}
diskUsageNameArrayIndex=$[diskUsageNameArrayIndex+1]
done
# 磁盘使用占比
diskUsageNameArrayIndex=0
for item in "${diskUsagePrecentTempArray[@]}"
do
diskUsagePrecentArray[diskUsageNameArrayIndex]=${item%%%}
diskUsageNameArrayIndex=$[diskUsageNameArrayIndex+1]
done
# 磁盘总大小
diskUsageNameArrayIndex=0
for item in "${diskUsageTotalSizeTempArray[@]}"
do
diskUsageTotalSizeArray[diskUsageNameArrayIndex]=${item%%%}
diskUsageNameArrayIndex=$[diskUsageNameArrayIndex+1]
done
# 磁盘已使用大小
diskUsageNameArrayIndex=0
for item in "${diskUsageUsedSizeTempArray[@]}"
do
diskUsageUsedSizeArray[diskUsageNameArrayIndex]=${item%%%}
diskUsageNameArrayIndex=$[diskUsageNameArrayIndex+1]
done
eval `ps -ef | grep vnc | awk '$8 ~ /\/usr\/sbin\/vncsession/ {printf("varActiveUserTempArray["NR"]=%s\n"), $9;printf("varActivePortTempArray["NR"]=%s\n"), $10}'`
# 获取处于占线中的用户名
varActivePortArrayIndex=0
for item in "${varActiveUserTempArray[@]}"
do
varActiveUserArray[varActivePortArrayIndex]=${item}
varActivePortArrayIndex=$[varActivePortArrayIndex+1]
done
# 循环数组 格式化端口号,获取处于占线中的端口号
varActivePortArrayIndex=0
for item in "${varActivePortTempArray[@]}"
do
varActivePortArray[varActivePortArrayIndex]=${item:1}
varActivePortArrayIndex=$[varActivePortArrayIndex+1]
done
# 设置内存默认最大占比
if [[ $memUsedPersentStandard = '' ]]
then
memUsedPersentStandard=$memUsedPersentStandardDefault
fi
# 设置允许最大vnc连接数
if [[ $maxVncConnectAmount = '' ]]
then
maxVncConnectAmount=$maxVncConnectAmountDefault
fi
echo -e "\n******************************创建vnc用户前置环境条件情况*********************************************"
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:正在检测前置环境条件情况..."
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:当前内存使用占比:$memUsedPersent%,最大允许内存使用率:$memUsedPersentStandard%,总内存大小:${memTotal}G,已使用的内存大小:${memUsed}G"
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:当前vnc在线的用户总数:${#varActivePortArray[@]},分别为:"
varActivePortArrayIndex=0
for item in "${varActivePortArray[@]}"
do
item=$[$item+5900]
processId="$(netstat -anp|grep $item|awk '{printf $7}'|cut -d/ -f1)"
vmRssSizeKb="$(cat /proc/$processId/status | awk -F '[ :]+' 'NR==22{print $3}')"
vmRssSizeMb="$(awk 'BEGIN{printf "%.2f\n",('$vmRssSizeKb'/'1024')}')"
echo -e "\t用户名:${varActiveUserArray[varActivePortArrayIndex]},端口号:$item,进程号:$processId,占用物理内存大小:${vmRssSizeKb}KB,约等于${vmRssSizeMb}Mb"
varActivePortArrayIndex=$[varActivePortArrayIndex+1]
done
varActivePortArrayIndex=0
# cpu使用占比
# cpu=`top -b -n5 | fgrep "Cpu(s)" | tail -1 | awk -F'id,' '{split($1, vs, ","); v=vs[length(vs)]; sub(/\s+/, "", v);sub(/\s+/, "", v); printf "%d", 100-v;}'`
# echo "[$(date '+%Y-%m-%d %H:%M:%S')]:当前cpu使用占比:${cpu}%"
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:当前各磁盘使用情况:"
diskUsageNameArrayIndex=0
for item in "${diskUsageNameArray[@]}"
do
echo -e "\t路径:${diskUsageNameArray[diskUsageNameArrayIndex]}\t 磁盘总大小:${diskUsageTotalSizeArray[diskUsageNameArrayIndex]}\t 磁盘已使用大小:${diskUsageUsedSizeArray[diskUsageNameArrayIndex]}\t 磁盘使用占比:${diskUsagePrecentArray[diskUsageNameArrayIndex]}%"
diskUsageNameArrayIndex=$[diskUsageNameArrayIndex+1]
done
####################################################################################################################################
if [[ $memUsedPersent -gt $memUsedPersentStandard ]]
then
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:linux用户创建失败、vnc创建失败,原因:当前内存使用占比:$memUsedPersent%,已超过最大允许内存使用率$memUsedPersentStandard%,总内存大小 ${memTotal}G,已使用的内存大小:${memUsed}G"
elif [[ ${#varActivePortArray[@]} -gt $maxVncConnectAmount ]]
then
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:linux用户创建失败、vnc创建失败,原因:当前用户在线连接vnc连接数为${#varActivePortArray[@]},已超过最大在线连接vnc连接数量$maxVncConnectAmount"
else
echo -e "\n******************************开始进行创建用户和vnc操作*********************************************"
# 将 selinux 设置为宽松模式
setenforce 0
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:selinux 设置为宽松模式"
# 设置用户默认密码
if [[ $userPasswd = '' ]]
then
userPasswd=$userPasswdDefault
fi
# 设置vnc默认密码
if [[ $vncPasswd = '' ]]
then
vncPasswd=$vncPasswdDefault
fi
# 设置代理 默认端口号
if [[ $noVncPort = '' ]]
then
noVncPort=$noVncDefaultMinPort
fi
# 判断linux用户信息是否已经已存在,如果不存在,创建其信息
if [ $userName != 'root' ]
then
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:正在检测到 家目录 $userHomeDefaultParentDir 是否存在..."
if [ ! -d "${userHomeDefaultParentDir}" ]
then
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:家目录 $userHomeDefaultParentDir 不存在,正在创建中..."
mkdir -p "${userHomeDefaultParentDir}"
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:家目录 $userHomeDefaultParentDir 创建成功"
else
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:家目录 $userHomeDefaultParentDir 已存在"
fi
checkUserIsExist "/$userName:/bin/bash"
if [[ $? -eq 0 ]]
then
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:检测到用户$userName 信息不存在,正在创建linux用户中..."
groupadd student
useradd -g student -d ${userHomeDefaultParentDir}/${userName} -m $userName
echo $userPasswd | passwd --stdin $userName;
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:linux用户$userName 创建成功"
fi
fi
# 循环读出已经开启的vnc 用户信息
for v in `grep -re "^:" /etc/tigervnc/vncserver.users`
do
v=${v:1}
tempSplitStr=($(splitStringFn $v "="))
if [[ ${tempSplitStr[1]} = $userName ]]
then
vncUserIsExist=1
port=$[$vncDefaultPort+${tempSplitStr[0]}]
maxPort=${tempSplitStr[0]}
break
fi
vncUserPortsArray[$vi]=${tempSplitStr[0]}
vncUserArray[$vi]=${tempSplitStr[1]}
vi=$[$vi+1]
done
if [ $vncUserIsExist -eq 0 ]
then
# 如果是非root用户,切换至普通用户下,设置并更改vncpasswd
if [ $userName != 'root' ]
then
expect << EOF
set timeout 1
spawn su - $userName
expect {
"*assword*" { send "$userPasswd\r" }
}
send "pwd\r"
# send "ps -ef | grep vnc\r"
send "vncpasswd\r"
expect {
"*Password*" { send "$vncPasswd\r";exp_continue }
"*Verify*" { send "$vncPasswd\r";exp_continue }
"*view-only*" { send "n\r" }
}
send "echo 'session=gnome' > ~/.vnc/config\n"
expect eof
EOF
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:用户 $userName vnc密码设置/更新成功"
else
echo 'session=gnome' > ~/.vnc/config
fi
# maxInArrayFn ${vncUserPortsArray[*]}
defaultPort=($(maxInArrayFn ${vncUserPortsArray[*]}))
maxPort=$[$defaultPort+1]
port=$[$vncDefaultPort+$maxPort]
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:当前在/etc/tigervnc/vncserver/users中的端口号有:${vncUserPortsArray[*]}"
findCanUsePortFn
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:当前用户 $userName 激活的vnc端口是:$port"
echo ":$maxPort=$userName" >> /etc/tigervnc/vncserver.users
cp -f /lib/systemd/system/vncserver@.service /etc/systemd/system/vncserver@:$maxPort.service
firewall-cmd --permanent --zone=public --add-port $port/tcp
firewall-cmd --reload
systemctl daemon-reload
# systemctl enable vncserver@:$maxPort.service
systemctl start vncserver@:$maxPort.service
# 如果在/etc/tigervnc/vncserver.users中查到用户已存在
else
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:用戶 $userName 信息在/etc/tigervnc/vncserver.users中查到已存在,正在检查对应的vnc端口:$port 是否处于运行中..."
checkPortIsInUseFn $port
# 如果端口号未占用,重新设置 用户session上
if [[ $? -eq 0 ]]
then
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:用戶 $userName 对应的vnc端口$port未运行,正尝试重新开启..."
expect << EOF
set timeout 1
spawn su - $userName
expect {
"*assword*" { send "$userPasswd\r" }
}
send "vncpasswd\r"
expect {
"*Password*" { send "$vncPasswd\r";exp_continue }
"*Verify*" { send "$vncPasswd\r";exp_continue }
"*view-only*" { send "n\r" }
}
send "echo 'session=gnome' > ~/.vnc/config\n"
expect eof
EOF
systemctl daemon-reload
firewall-cmd --permanent --zone=public --add-port $port/tcp
firewall-cmd --reload
# systemctl enable vncserver@:$maxPort.service
systemctl start vncserver@:$maxPort.service
else
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:用戶 $userName 对应的vnc端口$port已运行"
fi
# curl -H "Content-Length:0" -X GET "http://192.168.1.106:7002/demo?id=100"
fi
if [[ $(systemctl status vncserver@\:$maxPort.service | grep "active (running)") ]]
then
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:用户激活的vncserver成功~"
else
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:用户激活的vncserver失败~\r"
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:错误日志:"
systemctl status vncserver@\:$maxPort.service
journalctl -xe
fi
# 开启 novnc websockify 代理端口号
systemctl restart snapd.service
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:用戶 $userName 正在检查尝试开启novnc websockify 代理端口号:$noVncPort 是否被占用."
checkPortIsInUseFn $noVncPort
# 判断端口是否被占用,如果被占用
if [[ $? -eq 1 ]]
then
kill -9 $(netstat -anp|grep $noVncPort|awk '{printf $7}'|cut -d/ -f1)
fi
firewall-cmd --permanent --zone=public --add-port $noVncPort/tcp
firewall-cmd --reload
echo "snap set novnc services.n$noVncPort.listen=$noVncPort services.n$noVncPort.vnc=localhost:$port"
snap set novnc services.n$noVncPort.listen=$noVncPort services.n$noVncPort.vnc=localhost:$port
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:当前用户 $userName 成功开启novnc websockify代理端口号:$noVncPort"
echo -e "\n******************************总结*********************************************"
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:运行成功[success]"
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:用戶 $userName 对应的vnc端口是#currentPost:$port"
echo "[$(date '+%Y-%m-%d %H:%M:%S')]:用户 $userName 对应的novnc websockify代理端口号是#noVncPort:$noVncPort"
# 杀死指定端口的进程
# kill -9 $(netstat -anp|grep 10910|awk '{printf $7}'|cut -d/ -f1)
fi
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
上次更新: 2022/12/30, 23:48:21