-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathOracleShellInstall.sh
More file actions
6191 lines (6165 loc) · 236 KB
/
OracleShellInstall.sh
File metadata and controls
6191 lines (6165 loc) · 236 KB
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
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/usr/bin/env bash
#===============================================================================
# 文件名: OracleShellInstall
# 创建时间: 2022-06-18 12:32:09
# 修改时间: 2024-08-22 13:08:28
# 描述: Oracle Database Install for single/standlone/rac
# 路径: /soft/OracleShellInstall
# 版本: 5.0.0
# 作者: Lucifer(pc1107750981@163.com),bak724(bak724@163.com)
# 版权所有 (C) 2022-2099 Pengcheng Liu
#===============================================================================
# 导出 PS4 变量,以便 set -x 调试时输出行号和函数参数
export PS4='+${BASH_SOURCE}:${LINENO}:${FUNCNAME[0]}: '
#==============================================================#
# 全局变量定义 #
#==============================================================#
# 增加 bash 版本限制
bash_version=$(echo "$BASH_VERSION" | cut -d '.' -f1)
if [[ $bash_version ]] && ((bash_version < 4)); then
printf "\n\E[1;31m%-20s\n\E[0m\n" "本脚本不支持 Bash 版本低于 4 执行安装,当前 Bash 版本为:$bash_version,已退出!"
exit 1
fi
# 定义 rhel 系操作系统列表
rhel_os_list=(Red CentOS rhel centos ol rocky anolis uos kylin neokylin openEuler almalinux opencloudos ningos asianux NFS fedora euleros hce tencentos kos ctyunos)
# 定义 deb 系操作系统列表
deb_os_list=(debian ubuntu Deepin)
# 配置网络镜像源列表
net_os_list=(fedora euleros debian ubuntu Deepin arch hce)
# 配置本地镜像源列表
local_os_list=(Red CentOS rhel centos ol rocky anolis uos UOS kylin neokylin sles opensuse-leap opensuse-tumbleweed openEuler almalinux opencloudos ningos asianux NFS tencentos kos ctyunos)
# 定义未认证的国产化操作系统列表
unscertified_os_list=(rocky anolis kylin openEuler uos UOS fedora almalinux euleros ubuntu debian arch Deepin opencloudos ningos asianux NFS opensuse-leap opensuse-tumbleweed hce tencentos kos ctyunos)
# 定义 Oracle 官方认证的操作系统列表
oracle_certified_os_list=(centos CentOS Red rhel ol sles)
# 获取安装软件以及脚本目录(当前目录)
software_dir=$(dirname "$(readlink -f "$0")")
# 当前执行脚本系统时间
current=$(date +%Y%m%d%H%M%S)
# 删除脚本生成的 log 日志文件
find "$software_dir" -name "print_shell_install_*.log" -exec /bin/rm -rf {} +
find "$software_dir" -name "shell_install_output_*.log" -exec /bin/rm -rf {} +
# 脚本安装日志文件
oracleinstalllog=$software_dir/print_shell_install_$current.log
# 脚本输出日志文件
oracleprintlog=$software_dir/shell_install_output_$current.log
# 定义 os 认证标识
oracle_os_flag=NONE
# 物理内存(KB)
os_memory_total=$(awk '/MemTotal/{print $2}' /proc/meminfo)
# Swap 大小(KB)
swap_total=$(awk '/^SwapTotal:/ { print $2; }' /proc/meminfo)
# 计算额外需要的交换空间大小
((swap_count = (os_memory_total > 16777216 ? 16777216 : os_memory_total > 2097152 ? os_memory_total : os_memory_total * 3 / 2) - swap_total))
# 主机名称,单机和单机 ASM 模式是当前主机名;RAC 模式是主机名前缀;默认值为 orcl
hostname=orcl
# 数据库名称,默认值为 orcl,支持多个实例,传参以逗号隔开:orcl,oradb
db_name=orcl
# 是否 CDB 架构
declare -l iscdb=false
# PDB 名称,如果 PDB 名称有值,则默认为 CDB 架构,默认值为 pdb01,如果传入多个 PDB 名称,则创建多个 PDB,传参以逗号隔开:pdb01,pdb02,pdb03
pdbname=pdb01
# 系统用户 oracle 名称,默认值为 oracle
oracle_user=oracle
# 系统用户 oracle 密码,默认值为 oracle
oracle_passwd=oracle
# 数据库用户 sys/system 密码, 默认值为 oracle
database_passwd=oracle
# 数据库软件安装根目录,默认值为 /u01
env_base_dir=/u01
# 单机数据库参数,数据文件目录,默认值为 /oradata
oradata_dir=/oradata
# 数据库备份目录,默认值为 /backup
backup_dir=/backup
# 数据库字符集,默认值为 AL32UTF8
declare -u db_characterset=AL32UTF8
# 数据库国家字符集,默认值为 AL16UTF16
declare -u nation_characterset=AL16UTF16
# 数据库块大小,默认值为 8192
db_block_size=8192
# 数据库在线重做日志大小,默认值为 1024,单位 MB
redosize=1024
# 数据库是否开启归档模式
declare -l enable_arch=true
# 仅配置操作系统,默认值为 N,包括配置操作系统以及解压软件安装包
declare -u only_conf_os=N
# 安装到 Grid 软件结束,默认值为 N
declare -u install_until_grid=N
# 安装到 Oracle 软件结束,默认值为 N
declare -u install_until_db=N
# 是否优化数据库参数,默认值为 N
declare -u optimize_db=N
# 数据库安装架构,分为单机和 RAC
declare -l oracle_install_mode
# 是否安装图形化界面,默认值为 N
declare -u isgui=N
# 默认配置本地源,默认值为 Y
declare -u local_repo=Y
# 默认不配置网络源,默认值为 N
declare -u net_repo=N
# 默认不配置大页内存,默认值为 N
declare -u huge_flag=N
#==============================================================#
# RAC 模式全局变量定义 #
#==============================================================#
# RAC 节点号,默认为 1
node_num=1
# 定义一个存放所有 IP 的数组
declare -a allips
# 定义一个存放公网 IP 的数组
declare -a rac_public_ips
# 定义一个存放主机名的数组
declare -a rac_hostnames
# 定义一个存放 virtual ip 的数组
declare -a rac_virtual_ips
# 定义一个存放心跳网卡名称的数组
declare -a rac_priv_ifnames
# 定义一个存放 scan ip 的数组
declare -a rac_scan_ips
# 定义一个用于保存 root 用户需要设置 SSH 信任的 IP 地址
declare -a ssh_ips
# 定义用于保存心跳 IP 的关联数组
declare -A rac_priv_ips
# 定义数组 rac_priv_ifnames_sorted 用于存放排序后的 rac_priv_ifnames 数组
declare -a rac_priv_ifnames_sorted
# 用于存放 grid 静默文件 networkinterfacelist 数组
declare -a networkinterfacelist_array
# 存放 SSH 互信 IP 数组
declare -a hosts_array
# 系统用户 grid 名称,默认值为 grid
grid_user=grid
# 系统用户 grid 密码,默认值为 oracle
grid_passwd=oracle
# 是否配置 DNS 解析,默认值为 N
declare -u dns=N
# 是否配置 multipath 多路径,默认值为 Y
declare -u multipath=Y
# asm diskstring,默认值为 /dev/asm*
asmdisk_string="/dev/asm*"
# 是否配置 ASM 磁盘 UDEV 绑盘,默认值为 Y
declare -u asm_disk_conf=Y
# ASM 磁盘组名称,默认为 DATA,OCR,ARCH
declare -u ocr_asm_group=OCR
declare -u data_asm_group=DATA
declare -u arch_asm_group=ARCH
# ASM 磁盘组冗余度,默认值为 EXTERNAL,可选值为 [EXTERNAL|NORMAL|HIGH]
declare -u ocr_redun=EXTERNAL
declare -u data_redun=EXTERNAL
declare -u arch_redun=EXTERNAL
# 是否配置 AFD,默认值为 false
declare -l afd=false
# 是否配置 GIMR,默认值为 false
declare -l gimr=false
# 修复 VBOX BUG,如果使用 VBOX 划盘安装 RAC,则需要设置为 Y,默认值为 N
declare -u virtualbox=N
#==============================================================#
# 颜色打印 #
#==============================================================#
function color_printf() {
declare -u con_flag
declare -A color_map=(
["red"]='\E[1;31m'
["green"]='\E[1;32m'
["blue"]='\E[1;34m'
["yellow"]='\E[1;33m'
["light_blue"]='\E[1;94m'
["purple"]='\033[35m'
)
local res='\E[0m' default_color='\E[1;32m'
local color=${color_map[$1]:-"$default_color"}
case "$1" in
"red")
# 打印红色文本并退出
printf "\n${color}%-20s %-30s %-50s\n${res}\n" "$2" "$3" "$4"
exit 1
;;
"green" | "light_blue")
# 打印绿色或浅蓝色文本
printf "${color}%-20s %-30s %-50s\n${res}" "$2" "$3" "$4"
;;
"purple")
# 打印紫色文本并等待用户输入
printf "${color}%-s${res}" "$2" "$3"
read -r con_flag
# 如果用户未输入,默认为继续
if [[ -z $con_flag ]]; then
con_flag=Y
fi
if [[ $con_flag != "Y" ]]; then
echo
exit 1
fi
;;
*)
# 打印其他颜色文本
printf "${color}%-20s %-30s %-50s\n${res}\n" "$2" "$3" "$4"
;;
esac
}
#==============================================================#
# 日志打印 #
#==============================================================#
function log_print() {
echo
color_printf green "#==============================================================#"
color_printf green "$1"
color_printf green "#==============================================================#"
echo
}
#==============================================================#
# 执行命令并输出日志文件 #
#==============================================================#
function execute_and_log() {
local prompt="$1" cmd="$2" log_file="$oracleinstalllog" pid start_time end_time execution_time status
# 打印提示信息
echo -e "\e[1;34m${prompt}\e[0m\c"
printf "......"
# 记录开始时间
start_time=$(date +%s)
# 执行命令并将输出重定向到日志文件
if [[ $debug_flag == "Y" ]]; then
set -x
fi
eval "$cmd" >>"$log_file" 2>&1 &
if [[ $debug_flag == "Y" ]]; then
set +x
fi
pid=$!
# 显示进度条
while kill -0 "$pid" >/dev/null 2>&1; do
printf "."
sleep 0.5
printf "\b"
sleep 0.5
done
# 记录结束时间
end_time=$(date +%s)
execution_time=$((end_time - start_time))
# 等待命令执行完成
wait $pid
status=$?
# 根据命令执行状态打印结果
if ((status == 0 || status == 3)); then
printf "已完成 (耗时: %s 秒)\n" "$execution_time"
elif [[ $status != 0 ]]; then
case "$cmd" in
pkg_install | disable_firewall | conf_sysctl)
printf "已完成 (耗时: %s 秒)\n" "$execution_time"
;;
*)
printf "执行出错,请检查日志 %s\n" "$log_file"
exit 1
;;
esac
fi
}
#==============================================================#
# 脚本通用函数 #
#==============================================================#
function upper() {
# 将字符串转换为大写
echo "${1^^}"
}
function lower() {
# 将字符串转换为小写
echo "${1,,}"
}
function checkpara_NULL() {
# 检查参数是否为空
if [[ -z $2 || $2 == -* ]]; then
color_printf red "参数 [ $1 ] 的值为空,请检查!"
fi
}
function checkpara_YN() {
# 检查参数是否为 Y 或者 N
if ! [[ $2 =~ ^[YyNn]$ ]]; then
color_printf red "参数 [ $1 ] 的值 $2 必须为 Y 或者 N,请检查!"
fi
}
function checkpara_tf() {
# 检查参数是否为 Y 或者 N
if ! [[ $2 =~ ^(true|false)$ ]]; then
color_printf red "参数 [ $1 ] 的值 $2 必须为 true 或者 false,请检查!"
fi
}
function checkpara_REDUN() {
# 检查 RAC 参数是否为 EXTERNAL,NORMAL 或者 HIGH
local REDUN="EXTERNAL|NORMAL|HIGH"
if ! [[ $2 =~ ^($REDUN)$ ]]; then
color_printf red "RAC 参数 [ $1 ] 的值 $2 必须为 EXTERNAL,NORMAL 或者 HIGH,请检查!"
fi
}
function check_disknum() {
local disk_identifier=$1 redun=$2 normal=$3 high=$4 disk_count=$5
if [[ $redun == "NORMAL" ]]; then
if ((disk_count < normal)); then
color_printf red "$disk_identifier 磁盘组冗余度为 $redun 时,至少需要 $normal 块磁盘,请检查磁盘数量!"
fi
elif [[ $redun == "HIGH" ]]; then
if ((disk_count < high)); then
color_printf red "$disk_identifier 磁盘组冗余度为 $redun 时,至少需要 $high 块磁盘,请检查磁盘数量!"
fi
fi
}
function check_password() {
local password="$2"
# 密码中不能有不可见的控制字符,例如回车换行制表符等
if [[ $password =~ [[:cntrl:]] ]]; then
color_printf red "参数 [ $1 ] 的密码 $2 不符合要求,包含不可见字符,请检查!"
fi
if [[ $1 == "-dp" ]]; then
if ! [[ $password =~ ^[a-zA-Z][a-zA-Z0-9#$_]*$ ]]; then
color_printf red "参数 [ $1 ] 的密码 $2 不符合要求,必须以字母开头,并且字符只能包含 (_),(#),($) ,请检查!"
fi
fi
}
function checkpara_NUMERIC() {
# 检查参数是否为数字
if ! [[ $2 =~ ^[0-9]+$ ]]; then
color_printf red "参数 [ $1 ] 的值 $2 不是数字,请检查!"
fi
}
function checkpara_DBS() {
# 检查 db_block_size 参数值
local DBS="2048|4096|8192|16384|32768"
if ! [[ $2 =~ ^($DBS)$ ]]; then
color_printf red "参数 [ $1 ] 的值 $2 必须为 2048,4096,8192,16384 或者 32768,请检查!"
fi
}
function checkpara_DBCHARSET() {
# 所有有效字符集的列表 247 个
local CHARSETS="AL16UTF16|AL24UTFFSS|AL32UTF8|AR8ADOS710|AR8ADOS710T|AR8ADOS720|AR8ADOS720T|AR8APTEC715|AR8APTEC715T|AR8ARABICMAC|AR8ARABICMACS|AR8ARABICMACT|AR8ASMO708PLUS|AR8ASMO8X|AR8EBCDIC420S|AR8EBCDICX|AR8HPARABIC8T|AR8ISO8859P6|AR8MSWIN1256|AR8MUSSAD768|AR8MUSSAD768T|AR8NAFITHA711|AR8NAFITHA711T|AR8NAFITHA721|AR8NAFITHA721T|AR8SAKHR706|AR8SAKHR707|AR8SAKHR707T|AR8XBASIC|AZ8ISO8859P9E|BG8MSWIN|BG8PC437S|BLT8CP921|BLT8EBCDIC1112|BLT8EBCDIC1112S|BLT8ISO8859P13|BLT8MSWIN1257|BLT8PC775|BN8BSCII|CDN8PC863|CE8BS2000|CEL8ISO8859P14|CH7DEC|CL8BS2000|CL8EBCDIC1025|CL8EBCDIC1025C|CL8EBCDIC1025R|CL8EBCDIC1025S|CL8EBCDIC1025X|CL8EBCDIC1158|CL8EBCDIC1158R|CL8ISO8859P5|CL8ISOIR111|CL8KOI8R|CL8KOI8U|CL8MACCYRILLIC|CL8MACCYRILLICS|CL8MSWIN1251|D7DEC|D7SIEMENS9780X|D8BS2000|D8EBCDIC1141|D8EBCDIC273|DK7SIEMENS9780X|DK8BS2000|DK8EBCDIC1142|DK8EBCDIC277|E7DEC|E7SIEMENS9780X|E8BS2000|EE8BS2000|EE8EBCDIC870|EE8EBCDIC870C|EE8EBCDIC870S|EE8ISO8859P2|EE8MACCE|EE8MACCES|EE8MACCROATIAN|EE8MACCROATIANS|EE8MSWIN1250|EE8PC852|EEC8EUROASCI|EEC8EUROPA3|EL8DEC|EL8EBCDIC423R|EL8EBCDIC875|EL8EBCDIC875R|EL8EBCDIC875S|EL8GCOS7|EL8ISO8859P7|EL8MACGREEK|EL8MACGREEKS|EL8MSWIN1253|EL8PC437S|EL8PC737|EL8PC851|EL8PC869|ET8MSWIN923|F7DEC|F7SIEMENS9780X|F8BS2000|F8EBCDIC1147|F8EBCDIC297|HU8ABMOD|HU8CWI2|I7DEC|I7SIEMENS9780X|I8EBCDIC1144|I8EBCDIC280|IN8ISCII|IS8MACICELANDIC|IS8MACICELANDICS|IS8PC861|IW7IS960|IW8EBCDIC1086|IW8EBCDIC424|IW8EBCDIC424S|IW8ISO8859P8|IW8MACHEBREW|IW8MACHEBREWS|IW8MSWIN1255|IW8PC1507|JA16DBCS|JA16DBCSFIXED|JA16EBCDIC930|JA16EUC|JA16EUCFIXED|JA16EUCTILDE|JA16EUCYEN|JA16MACSJIS|JA16SJIS|JA16SJISFIXED|JA16SJISTILDE|JA16SJISYEN|JA16VMS|KO16DBCS|KO16DBCSFIXED|KO16KSC5601|KO16KSC5601FIXED|KO16KSCCS|KO16MSWIN949|LA8ISO6937|LA8PASSPORT|LT8MSWIN921|LT8PC772|LT8PC774|LV8PC1117|LV8PC8LR|LV8RST104090|N7SIEMENS9780X|N8PC865|NDK7DEC|NE8ISO8859P10|NEE8ISO8859P4|NL7DEC|RU8BESTA|RU8PC855|RU8PC866|S7DEC|S7SIEMENS9780X|S8BS2000|S8EBCDIC1143|S8EBCDIC278|SE8ISO8859P3|SF7ASCII|SF7DEC|TH8MACTHAI|TH8MACTHAIS|TH8TISASCII|TH8TISEBCDIC|TH8TISEBCDICS|TR7DEC|TR8DEC|TR8EBCDIC1026|TR8EBCDIC1026S|TR8MACTURKISH|TR8MACTURKISHS|TR8MSWIN1254|TR8PC857|US7ASCII|US8BS2000|US8ICL|US8PC437|UTF8|UTFE|VN8MSWIN1258|VN8VN3|WE8BS2000|WE8BS2000E|WE8BS2000L5|
WE8DEC|WE8DG|WE8EBCDIC1047|WE8EBCDIC1047E|WE8EBCDIC1140|WE8EBCDIC1140C|WE8EBCDIC1145|WE8EBCDIC1146|WE8EBCDIC1148|WE8EBCDIC1148C|WE8EBCDIC284|WE8EBCDIC285|WE8EBCDIC37|WE8EBCDIC37C|WE8EBCDIC500|WE8EBCDIC500C|WE8EBCDIC871|WE8EBCDIC924|WE8GCOS7|WE8HP|WE8ICL|WE8ISO8859P1|WE8ISO8859P15|WE8ISO8859P9|WE8ISOICLUK|WE8MACROMAN8|WE8MACROMAN8S|WE8MSWIN1252|WE8NCR4970|WE8NEXTSTEP|WE8PC850|WE8PC858|WE8PC860|WE8ROMAN8|YUG7ASCII|ZHS16CGB231280|ZHS16CGB231280FIXED|ZHS16DBCS|ZHS16DBCSFIXED|ZHS16GBK|ZHS16GBKFIXED|ZHS16MACCGB231280|ZHS32GB18030|ZHT16BIG5|ZHT16BIG5FIXED|ZHT16CCDC|ZHT16DBCS|ZHT16DBCSFIXED|ZHT16DBT|ZHT16HKSCS|ZHT16HKSCS31|ZHT16MSWIN950|ZHT32EUC|ZHT32EUCFIXED|ZHT32SOPS|ZHT32TRIS|ZHT32TRISFIXED"
# 检查参数是否在有效字符集列表中
if ! [[ $2 =~ ^($CHARSETS)$ ]]; then
color_printf red "数据库字符集参数 [ $1 ] 的值 $2 无效,请检查!"
fi
}
function checkpara_NCHARSET() {
# 所有有效字符集的列表
local NCHARSETS="UTF8|AL16UTF16"
# 检查参数是否在有效字符集列表中
if ! [[ $2 =~ ^($NCHARSETS)$ ]]; then
color_printf red "国家字符集参数 [ $1 ] 的值 $2 无效,请检查!"
fi
}
function check_DBNAME() {
local dbname="$1"
local regex="^[a-zA-Z0-9]+$"
if ! [[ $dbname =~ $regex ]]; then
color_printf red "参数 [ -o ] 的值 $dbname 不符合要求,请使用数字和字母,不要使用特殊字符,请检查!"
fi
}
function check_RACNAME() {
# 检查参数是否为数字
if [[ $2 =~ ^[0-9] ]]; then
color_printf red "参数 [ $1 ] 的值 $2 不能使用数字开头,请检查!"
fi
}
function check_file() {
# 检查文件是否存在
if [[ -e "$1" ]]; then
return 0
else
return 1
fi
}
function mv_file() {
local file_path=$1
# 检查原始文件是否存在
if ! check_file "$file_path".original; then
# 检查文件是否存在
if check_file "$file_path"; then
# 不存在则备份为原始文件
/bin/mv -f "$file_path"{,.original} >/dev/null 2>&1
fi
fi
}
function rm_file() {
local file=$1
# 检查文件是否存在
if check_file "$file"; then
# 不存在则备份为原始文件
/bin/rm -rf "$file" >/dev/null 2>&1
fi
}
function backup_restore_file() {
local file_path=$1
if check_file "$file_path"; then
if (($(grep -E -c "# OracleBegin" "$file_path") == 0)); then
/bin/cp -f "$file_path"{,.original}
else
/bin/cp -f "$file_path"{,."$current"}
/bin/cp -f "$file_path"{.original,}
fi
else
touch "$file_path".original
fi
}
function write_file() {
local flag=$1 file_name=$2 content=$3
if [[ $flag == "Y" ]]; then
cat <<-EOF >"$file_name"
$content
EOF
elif [[ $flag == "N" ]]; then
cat <<-EOF >>"$file_name"
$content
EOF
fi
}
function run_as_oracle() {
local command="$1"
su - $oracle_user -c "bash -l -c \"$command\""
}
function run_as_grid() {
local command="$1"
su - $grid_user -c "bash -l -c \"$command\""
}
function execute_sqlplus() {
local dbname="$1" format="$2" sql="$3"
su - $oracle_user <<-SOF
source /home/$oracle_user/.$dbname
sqlplus -S / as sysdba<<-\EOF
set lin 2222 pages 1000 tab off feedback off
$format
$sql
exit;
EOF
SOF
}
function check_ip() {
# 检查 IP 地址格式是否正确
local ip=$1
if echo "$ip" | grep -Eq "^([0-9]{1,3}\.){3}[0-9]{1,3}$"; then
return 0
else
return 1
fi
}
function check_ip_connectivity() {
# 检查 IP 地址是否可以 ping 通
local ip=$1
if ! ping -c 1 "$ip" >/dev/null 2>&1; then
color_printf red "IP地址 $ip 无法 ping 通,请检查!"
fi
}
function check_ip_unreachability() {
# 检查 IP 地址是否可以 ping 通
local ip=$2
if ping -c 1 "$ip" >/dev/null 2>&1; then
color_printf red "RAC $1 的 $ip 可以被 ping 通,可能被占用,请检查!"
fi
}
function isunique_ip() {
# 检查 IP 地址是否唯一
declare -A ip_count
for ip in "${allips[@]}"; do
((ip_count[$ip]++))
done
for ip in "${!ip_count[@]}"; do
if ((ip_count[$ip] > 1)); then
color_printf red "IP地址 $ip 存在重复,请检查!"
fi
done
}
function check_internet_connectivity() {
# 检查网络连接是否正常
if ! ping -c 1 www.baidu.com >/dev/null 2>&1; then
color_printf red "脚本参数 [ -nrp ] 值为 $net_repo,当前操作系统 [ $pretty_name ] 需要配置网络软件源,必须联网,否则安装失败!"
fi
}
#==============================================================#
# GET WWID #
#==============================================================#
function get_wwid() {
local wwid scsi_id
# 根据操作系统版本设置 scsi_id 命令路径
if ((os_version == 6)); then
scsi_id="/sbin/scsi_id"
else
scsi_id="/usr/lib/udev/scsi_id"
fi
# 获取磁盘的 WWID
wwid=$("$scsi_id" -g -u "$1")
echo "$wwid"
}
#==============================================================#
# Clean Disk #
#==============================================================#
function clean_disk_and_get_wwid() {
local wwid_list wwid wwid_string identifier=$2 disk_count
# 使用传入的磁盘列表,以逗号分隔的字符串
IFS=',' read -ra disks <<<"$1"
disk_count=${#disks[@]}
# 遍历处理每个磁盘
for disk in "${disks[@]}"; do
if [[ -n "$disk" ]]; then
# 检查磁盘头部
if hexdump -C -n 102400 "$disk" | grep -q "$identifier"; then
color_printf purple "检查 ASM 磁盘 [ $disk ] 中已存在磁盘组名称 [ $identifier ] 信息,请确认是否格式化磁盘 (Y/N): [Y] "
echo
dd if=/dev/zero of="$disk" bs=4096 count=1 >/dev/null 2>&1
fi
# 获取磁盘 WWID
wwid=$(get_wwid "$disk")
if [[ -z "$wwid" ]]; then
color_printf red "磁盘 $disk 的 WWID 未获取到,请检查磁盘!"
fi
wwid_list+=("$wwid")
fi
done
# 将磁盘 WWID 列表转换为逗号分隔的字符串
wwid_string=$(
IFS=,
echo "${wwid_list[*]}"
)
# 根据标识符设置全局变量的磁盘 WWID
case "$identifier" in
"OCR")
ocr_disk_wwid="$wwid_string"
check_disknum "$identifier" "$ocr_redun" 3 5 "$disk_count"
;;
"DATA")
data_disk_wwid="$wwid_string"
check_disknum "$identifier" "$data_redun" 2 3 "$disk_count"
;;
"ARCH")
arch_disk_wwid="$wwid_string"
check_disknum "$identifier" "$arch_redun" 2 3 "$disk_count"
;;
esac
}
#==============================================================#
# Conf Disk && GET WWID #
#==============================================================#
function conf_disk_wwid() {
if [[ $asm_disk_conf == "N" ]]; then
datadisk=$data_base_disk
ocrdisk=${ocr_base_disk:+"$ocr_base_disk"}
archdisk=${arch_base_disk:+"$arch_base_disk"}
# 构建 ASM 磁盘路径模式,格式为:磁盘目录/磁盘名前三个字符*
asmdisk_string="$(dirname "${data_base_disk##*,}")/$(echo "${data_base_disk##*/}" | cut -c1-3)""*"
else
# 获取 ASM 磁盘 WWID 并格式化磁盘头
local disk_types=("OCR" "DATA" "ARCH")
# 循环遍历磁盘类型,处理每种磁盘
for disk_type in "${disk_types[@]}"; do
local base_disk="${disk_type,,}_base_disk"
if [[ "${!base_disk}" ]]; then
clean_disk_and_get_wwid "${!base_disk}" "$disk_type"
fi
done
fi
}
#==============================================================#
# 过滤唯一 wwid 磁盘 #
#==============================================================#
function filter_disk() {
local fil_disk=$1 all_disks disk disk_list=() wwid
declare -A wwids sizes
# 获取磁盘存储大小的函数,返回值以 GB 为单位
disk_storage() {
lsblk -b -o SIZE,TYPE "${1}" | awk '$2 == "disk" {print $1/1024/1024/1024 "G"}'
}
# 获取所有磁盘名,以 sd 或 vd 开头的磁盘
all_disks=$(lsblk -n -o NAME | awk '/^sd|vd/ { print $1 }')
# 解析传入的过滤磁盘列表
IFS=',' read -ra fil_disk_arr <<<"$fil_disk"
# 过滤磁盘列表,排除在过滤列表中的磁盘
for disk in $all_disks; do
if ! [[ "${fil_disk_arr[*]}" =~ $disk ]]; then
disk_list+=("/dev/$disk")
fi
done
# 获取每个磁盘的大小和 WWID
for disk in "${disk_list[@]}"; do
sizes[$disk]=$(disk_storage "$disk")
wwid=$(get_wwid "$disk")
if [[ -n $wwid && ! "${wwids[*]}" =~ $wwid ]]; then
wwids[$disk]=$wwid
fi
done
# 打印磁盘信息
color_printf light_blue "Disk WWID" "Disk Name" "Size"
for disk in "${!wwids[@]}"; do
color_printf green "${wwids[$disk]}" "$disk" "${sizes[$disk]}"
done | sort -k3,3n -k2,2
}
#==============================================================#
# SSH Check #
#==============================================================#
function ssh_check() {
local user=$1 all_connections_ok="true"
# 定义存放主机 IP 地址的数组
declare -a ips=("${@:2}")
# 循环遍历主机 IP 地址列表
for ip in "${ips[@]}"; do
# 使用 su 切换到指定用户,执行 ssh 命令检查连接
if su -s /bin/bash -c "ssh -q -o ConnectTimeout=1 -o ConnectionAttempts=1 -o PreferredAuthentications=publickey -o StrictHostKeyChecking=no $ip date" "$user" >/dev/null 2>&1; then
all_connections_ok="true"
else
# 如果某个连接失败,则标识 all_connections_ok 置为 false,并跳出循环
all_connections_ok="false"
break
fi
done
# 输出连接状态
echo $all_connections_ok
}
#==============================================================#
# SSH Trust #
#==============================================================#
function ssh_trust() {
# 获取目标用户名和密码
local dest_user=$1 passwd ssh_dir
passwd=$(printf "%q" "$2")
# 定义存放主机 IP 地址的数组
declare -a host_ips=("${@:3}")
# 判断是否是 root 用户,设置 SSH 目录路径
[[ $dest_user == "root" ]] && ssh_dir="/root/.ssh" || ssh_dir="/home/$dest_user/.ssh"
# 如果目标路径存在,删除该路径
if [[ -e "$ssh_dir" ]]; then
/bin/rm -rf "$ssh_dir"
fi
# 创建 SSH 目录并设置目录权限
/bin/mkdir -p "$ssh_dir" && chmod 755 "$ssh_dir"
# 生成 SSH 密钥
ssh-keygen -t rsa -P '' -f "$ssh_dir/id_rsa"
# 将公钥添加到 authorized_keys 文件并设置文件权限
cat "$ssh_dir/id_rsa.pub" >>"$ssh_dir/authorized_keys" && chmod 644 "$ssh_dir/authorized_keys"
# 填充 expect 缓存
for ip in "${host_ips[@]}"; do
expect <<EOF >/dev/null 2>&1
set timeout 300
spawn ssh -q -o StrictHostKeyChecking=no $dest_user@$ip "echo 'Connected!'"
expect "password:" { send "$passwd\r"; exp_continue } eof { exit } timeout { puts "等待超时,检查 ssh 执行速度"; exit 1 }
EOF
done
# 循环遍历主机 IP 地址列表,将 ssh 目录复制到目标主机
for ip in "${host_ips[@]}"; do
expect <<EOF >/dev/null 2>&1
set timeout 300
spawn scp -q -o StrictHostKeyChecking=no -r $ssh_dir $dest_user@$ip:~
expect "password:" { send "$passwd\r"; exp_continue } eof { exit } timeout { puts "等待超时,检查 scp 执行速度"; exit 1 }
EOF
# 如果 os 版本为 6,则执行 restorecon 命令恢复文件安全上下文
if ((os_version == 6)); then
expect <<EOF >/dev/null 2>&1
set timeout 300
spawn ssh -q -o StrictHostKeyChecking=no $dest_user@$ip restorecon -RF $ssh_dir
expect "password:" { send "$passwd\r"; exp_continue } eof { exit } timeout { puts "等待超时,检查 ssh 执行速度"; exit 1 }
}
EOF
fi
done
# 等待所有子进程完成
wait
}
#==============================================================#
# 适配国产系统 #
#==============================================================#
function create_symlink() {
local flag=$1 source_path=$2 destination_path=$3
# 根据标志创建软链接
if [[ $flag == "Y" ]]; then
# 强制创建软链接
ln -sf "$source_path" "$destination_path" >/dev/null 2>&1
elif [[ $flag == "N" ]]; then
# 创建软链接
ln -s "$source_path" "$destination_path" >/dev/null 2>&1
fi
}
# 定义函数 base64_to_binary
# 压缩命令 tar -cJf stat.tar.xz libaio.so.1 stat-stubs.o
# 生成字符串 base64 stat.tar.xz >stat.txt
# 解码并保存到 stat.tar.gz
# base64_to_binary "$base64_string" stat.tar.xz
# 解压 tar -xJf stat.tar.xz
function base64_to_binary() {
local base64_string=$1 output_file="${2:-decoded.bin}"
# 将 Base64 字符串解码并保存到指定的文件
echo -n "$base64_string" | base64 --decode >"$output_file"
}
# 定义一个函数来检查操作系统是否在给定列表中
function is_in_list() {
local item=$1
shift
local list=("$@")
for element in "${list[@]}"; do
if [[ "$item" == "$element" ]]; then
return 0
fi
done
return 1
}
function check_md5sum() {
local file_name=$1
local expected_md5=$2
color_printf green "正在检测安装包 $file_name 的 MD5 值是否正确,请稍等......"
if [[ $(md5sum "$file_name" | awk '{print $1}') != "$expected_md5" ]]; then
color_printf red "请检查 $file_name 文件的完整性,确保 md5sum 值为 $expected_md5!"
fi
}
# 检查 Oracle 兼容性
function check_oracle_compatibility() {
check_version_compatibility() {
local supported_versions="$1"
# 检查操作系统版本是否兼容
if [[ "$os_version" =~ ^($supported_versions)$ ]]; then
oracle_os_flag=Y
else
oracle_os_flag=N
fi
}
# 检查未认证的国产化操作系统
check_unscertified_os() {
if is_in_list "$os_type" "${unscertified_os_list[@]}"; then
oracle_os_flag="N"
fi
}
# 检查 Oracle 曾经认证过的国产数据库操作系统
check_neokylin_os() {
if [[ "$os_type" == "neokylin" ]]; then
if ((db_version == 11 && os_version == 7)); then
oracle_os_flag="Y"
else
oracle_os_flag="N"
fi
fi
}
# 检查 Oracle 官方认证的操作系统
check_oracle_certified_os() {
if is_in_list "$os_type" "${oracle_certified_os_list[@]}"; then
if [[ $cpu_type == "aarch64" ]]; then
if [[ "$os_type" == "ol" ]]; then
check_version_compatibility "8"
else
oracle_os_flag="N"
fi
else
if [[ "$os_type" == "sles" ]]; then
case "$db_version" in
11) check_version_compatibility "7" ;;
12 | 19) check_version_compatibility "7|8" ;;
21) check_version_compatibility "8" ;;
26) oracle_os_flag="N" ;;
esac
else
case "$db_version" in
11 | 12) check_version_compatibility "6|7|8" ;;
19) check_version_compatibility "7|8|9" ;;
21) check_version_compatibility "7|8" ;;
26) check_version_compatibility "8|9" ;;
esac
fi
fi
fi
}
check_unscertified_os
check_neokylin_os
check_oracle_certified_os
if [[ "$oracle_os_flag" == "N" ]]; then
color_printf purple "!!! 免责声明:当前操作系统版本是 [ $pretty_name ] 不在 Oracle 官方支持列表,本脚本只负责安装,请确认是否继续安装 (Y/N): [Y] "
echo
elif [[ "$oracle_os_flag" == "NONE" ]]; then
color_printf red "当前操作系统版本是 [ $pretty_name ] 不在脚本支持列表中,如有需要请联系开发者适配!"
fi
}
function ar_libc_nonshareda() {
local base64_string
if [[ $cpu_type == "aarch64" ]]; then
base64_string='/Td6WFoAAATm1rRGAgAhARYAAAB0L+Wj4Mf/CMZdADMcyt3f9REpe7Mql4Z72aQIt6Fkqj2Aq3SG
JjDLcH6dOLVuP818vA+C+aczpNGBpgE06wvrW45stoi4Z5iGhOHrm4sTBVpuZwov9TVD6PBSlvGb
pailsXIFMOU3h/eYiYEc7h9NkzplDHOsQFxwmD/RmfdSG/WTUmguftOCt85HXW+5KNxKeBK54I1F
rFiH7Z6eoAivlTM0VchNtfKT8CknW3GbG6YS1RqpywczbnggQW4W8tQGruI/PcnZfttd1e/+MzVM
89w8BeEAHCTdBJ2syEJ55kafLFnN681ogUuDA5AE6F+cz88lHSz9J0STAAcZQNH1MMYKtv1kNZ9Z
rkj7aFr6lcrgpRJvk0ResulNroK46JM52sI1zg3ii/lxS/vjYz8W5G12FvNPmotZj9atz5be8TK4
EGF3VDDi2TYfzqV4zue/2Q4NXAcRtDV4BNkKnJG9muXHhKiVASJiohYCv9CJCIv2j0wtBqXgMJng
heKO3ptYP7gv5E76wg9iTkLgQvwanULVmn18KVqc422MM6VTzl3eUc0YjPV64lEsL3+mpNCa+vUl
8Dz0B90eOZztQmk58xZqSmAc8cKgCBFM3oWJYbVPud+bHltzYxEWUI+7TtV5+wFrcQh2xrb21JZw
VV21g1qtcmnE+3qY9RNXgfbqFdynABQ4vuIie4q/XQKOerD5CspVF0AhztL9vlWgg+fMO/I56yCX
8k1z/3MXNkpOUYATuU99U6ASXcTmHEZ9WblcIJx3YgnoqSXphiwpJDbiZ/dBF0K3n+wXJrCayXWb
z/Wj7BsXYTfGga1vYGyECRTj/jiJ0/tlN9J7MR0m3aS5IJ8duuuMjByWa4qDLtE+UQCpbolnoy4U
l1JchXAoxZGGOks1nJfF//uuhlkhgvwP/hFknPqt7jZAAWQphjDcVneTwLFPZC4k4OxdK1yVNPud
Chcz27uay+NOQ+GKF5hVTL6DLvIt/YSOiYhhL3u4srXTZETgIZOVaxXUbLwd9KDPM1jv2wpgkmXt
S5wkLVQXSiQ4y7qAdEltD0+g59WQZKLcfoWu9kfx16JfCZiyFMbJvSM/U1szMHYCMBt/ZHbiCabN
XkPmNsuSaDpUYeuNKurVm+0f8gMyY6Q9mCEXz1jA0nbBzAXVo04Iih3p80B1rvOhUnnT8Ml3zZYz
gI0rllX2xhigD+bIzJhpeiM0DzKC/sQiJ0nM8crgB1NR46ItjXBz0Ade1PChMM7rFLah/vC16o7t
O6iFJg5sWSpGFRi+KdrZat2klTNqsDjrfz1AXqFKfnGRelma5cfSO99cLDauiL1cYqHJfVBvEeUL
uwAJJlFXrWSyAxK3UPmWyPIK+wsCNqKcmqnh3woz/gTs/sVURc36PXRytXqW+wQqIKCQJu3T+Ixw
Fhti9SuGiEmeVmjQPwVOVpBW16ozX099mXw89f2WBups3MfTk1YJZtgdnCVeolZi8L2nzvDaeABZ
A1VjFgNCRni0IMOd3JD3p3YIevm6L//VqyOHf+P8J5wFNPR7AbtTq4o8dLxAz0YXqhjPETFStpMN
HetI/BhFzxSZuLcHzKCq5jvpX1TfL8mDavDuVjliEL27uCTSmDZGlihAS8GSL7zhycyJ8db5Up8d
Thf1ca4M7OxHKJ3/D7j0kg2AaayHDuflUiJJGRmh+XnuePGJmK809EmI0jsmDZ8UdjMRlflP1MMv
TztwRB7JjicM9iyKGlATtx7e7iOSqrdolBZt1juRLOXsDrdaXVoav5KMqU8At4fSHs91AQgiSDo0
85IVUngLVb26VIsWA+QWItAu17s2k9R7608Nh0fDnCrPQX1nuM9FGJFFOYMWHc2t4vasoBQcSK/j
oZarmJxMy7o2+nS6STqU6WieTfhGSnFxwqKZLRUEfc1t+uUyelp+BRmoB6LP67vS1rIlIGRRZSMK
x3opa+G1U0tiSeTBt4Wk/vA6d4Gq6MszDGj8vt5rdJcaK3FdgwF/sa7Mhsr3nJ5XKrRvJQ04tdpu
DrhaJpn1mDLcWv4lUSxWG4VfBIfJnlupGPRrNZVjmyxZtvuhpPIWkwb0opBLAgnp1ueLmmBC9CpL
JaNc852qF7VBKI6UNKdMVovqyBO/DLMfGMEj6xouEOIWqXF/frO2ytdJfW0BEwUjvluK2xbBCBww
o/5WJIVn0zRw0wVnktxSRspbdYL4WDDlnqse0ibwo7lLnJiC0CaluYvouTvxfuSNwS6EjJpjJjin
u58cY0L2Z04fGHeCVKfkufSXjzby5KRIR/ZO5NCX5wo39SJsamrgA5QzAnEAIM5lJKcq0RkR5wTm
6K/qeNcJpz0qKe5sHxuF+hO59ayMlllUUCOry1fT/Lhz8nceAJauIrIVDaFZfwPRHcpH+ehSkJCG
sS3waiwn/4k90HJXynLxOgkPjbtiXatU/tyrwX/BXceRJIUIQgnv+XcLL0S3sHqrY35UWeo3PENQ
JoxC8Jq0jrYhdDE8MXgUrJpbEXtagTL7IBQ5xvl7CacwJ8/UclUXLU5/Bvzs9wsHVe36oJI0oZxP
Mg1azJly9rSykO70Ga5OC2JLLE9cW+gInssifTIcmHGoiqOtmzqMX7udo1TpwV9GUc3eUAr9D5Ck
4bYJncIJB1HisH6Gyh+An6jFDh8utoH+6z392WP3C1LZ0k8rx6i0jgDKjMNhZh2P2XWY+amZmp7n
CXxpNaUO6JspQKUkhTjWrlLIaofzWQaTB8sKzMIYsCx+2ymBcL2OsCQvaRcqiXRIScl6g96objAA
15JIjMNoyzMbdFd/+hy2bxyPRV7uwkr6QOdYHYCYTC0LndLoaylRxcKjBNbi88mf2cdqnDPusRLv
BIB3/2IioRma9rMOc+O1z4HzuEJWRPwCO9L91s8JHSDW4tBM8mBgqHwhM4McVo8h7sPt8/wTlZav
aVI8cABjfq+slqqd96hKhue2QGqhne+UWsbRvGEexKWRrTifeCqN6okMpp8a4kUtLkjEte8PAAAA
7CA44DTdJK8AAeIRgJADAG6NPv6xxGf7AgAAAAAEWVo='
# 解码并保存到 stat.tar.xz
stat_array=(
"$software_dir/fstat64.oS"
"$software_dir/lstat64.oS"
"$software_dir/lstat.oS"
"$software_dir/stat64.oS"
"$software_dir/fstatat64.oS"
"$software_dir/mknod.oS"
)
else
base64_string='/Td6WFoAAATm1rRGAgAhARYAAAB0L+Wj4Cf/Af1dADmdCEcK2iXKM9hlSqnJgOklzkj59aGHLFqo
DWNfS87u1zfN2ZEKKUt1dO9GLhDuvHtQQqc4ljXoBmNoK5BLs+vNuOEwa3Hm/IJ9OFH2vxiu+g/a
e98u5sOg1WX22b+A/pm+zW843A9s8M6wHYfjKqp13DxrDtyB/H0Mju2tV8oZ+8mOM4xSPfnM7keT
O69cMufEh5jKsCOL8n2mwAadM/X7/susSp+ThkmiKFzvwpL6pSBIZAZ9NnhyGt+Mb+3z/oh0v/QE
Q9/Sebsd+kdAIYxrlnyR6QwA46RXUx9CUv1WlN9G/mHcK86Jp9y5OTT8/ObWzDLX9OE1y/NzHsYO
riL7LxJAoJbv5iNuakmBHTHLVcNiqcS4A+y3cJpiw+yfqr+/NjpmB/pw9UPhpmMCDX2dS35TPbTl
5mww27aAvuE7WVT25Q6gOZ7VVh7gw2pnoXlvaBH480FmOhMB+5U9mtcbMAoKyYaDhvtjKpfx8l3I
Lq6xlN76sfL3EencD4k8zC+42nLb/sjofaJADN1suSMWUPAFZWrxKaInDdfWCOy764JKBAtMPcia
2l0ltIc7jJ2RzZob591N5iwY2xjcVvQQNv2VJHM6wM3Mw8s6RIjZlP9WeXzFNhWHTl9UZ25RMKe8
DS7PiRyfdum+4wnQckYYvXeWpHSOVp9zq8ngAAAAAHfXVLs/p0kvAAGZBIBQAAAdrVmNscRn+wIA
AAAABFla'
# 解码并保存到 stat.tar.xz
stat_array=(
"$software_dir/stat-stubs.o"
)
fi
# 解码并保存到 stat.tar.xz
for stat in "${stat_array[@]}"; do
if ! check_file "$stat"; then
base64_to_binary "$base64_string" "$software_dir/stat.tar.xz"
tar -xJf "$software_dir"/stat.tar.xz -C "$software_dir" >/dev/null 2>&1
fi
## 适配 libc_nonshared
ar r "$a_path"/libc_nonshared.a "$stat" >/dev/null 2>&1
done
}
function create_libpthreada() {
# 适配 debs,事先建立 /usr/lib64
/bin/mkdir -p /usr/lib64
# 检查并创建 libpthread_nonshared.a
# 因 libpthread_nonshared.a libc_nonshared.a 路径是 Oracle 硬编码,无需 so_path
if ! check_file /usr/lib64/libpthread_nonshared.a; then
ar cr /usr/lib64/libpthread_nonshared.a >/dev/null 2>&1
chmod a+rx /usr/lib64/libpthread_nonshared.a
fi
}
function do_fix_libaio() {
local base64_string
base64_string='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'
# 解码并保存到 libaio.tar.xz
if ! check_file "$software_dir"/libaio.so.1; then
base64_to_binary "$base64_string" "$software_dir/libaio.tar.xz"
tar -xJf "$software_dir"/libaio.tar.xz -C "$software_dir" >/dev/null 2>&1
fi
# 链接 libaio
if ! check_file "$so_path"/libaio.so.1.original; then
if check_file "$so_path"/libaio.so.1; then
/bin/mv -f "$so_path"/libaio.so.1 "$so_path"/libaio.so.1.original >/dev/null 2>&1
fi
if check_file "$software_dir"/libaio.so.1; then
/bin/cp -f "$software_dir"/libaio.so.1 "$so_path"/libaio.so.1 >/dev/null 2>&1
chmod a+rx "$so_path"/libaio.so.1
fi
fi
}
function do_fix_libnsl() {
# 修复 libnsl,主要针对单机模式,RAC 必须要安装 libnsl* 包
if ! check_file "$a_path"/libnsl.so; then
if check_file "$so_path"/libnsl.so.2; then
create_symlink "N" "$so_path"/libnsl.so.2 "$a_path"/libnsl.so
elif check_file "$so_path"/libnsl.so.3; then
create_symlink "N" "$so_path"/libnsl.so.3 "$a_path"/libnsl.so
fi
fi
if ! check_file "$so_path"/libnsl.so.1; then
if check_file "$so_path"/libnsl.so.2; then
create_symlink "N" "$so_path"/libnsl.so.2 "$so_path"/libnsl.so.1
elif check_file "$so_path"/libnsl.so.3; then
create_symlink "N" "$so_path"/libnsl.so.3 "$so_path"/libnsl.so.1
fi
fi
if [[ $cpu_type == "aarch64" ]]; then
if ! check_file "$so_path"/libnsl.so.2; then
if check_file "$a_path"/libnsl.so; then
create_symlink "N" "$so_path"/libnsl.so "$a_path"/libnsl.so.2
fi
fi
fi
}
function do_fix_libcap() {
# 修复 libcap.so,libcap.so.1
if ! check_file "$so_path"/libcap.so; then
create_symlink "N" "$so_path"/libcap.so.2 "$a_path"/libcap.so
fi
if check_file "$so_path"/libcap.so.2; then
if ! check_file "$so_path"/libcap.so.1; then
create_symlink "N" "$so_path"/libcap.so.2 "$so_path"/libcap.so.1
fi
fi
}
function do_fix_so() {
do_fix_libnsl
do_fix_libcap
# 适配 11GR2 安装
if ((db_version == 11)); then
if [[ "$os_type" =~ ^(ubuntu|debian|Deepin)$ ]]; then
adapt_gcc
fi
do_fix_libaio
fi
if [[ $cpu_type == "aarch64" ]]; then
if [[ "$os_type" =~ ^(ubuntu|debian|Deepin)$ ]]; then
adapt_gcc
fi
fi
}
# 在 OpenSSH 升级到 8.x 后 GI 安装失败 INS-06006 (Doc ID 2639907.1)
# GI runInstaller Fails with INS-6006 despite fixing Bug 30159782 (Doc ID 2921432.1)
function adapt_scp() {
local scp_ver
scp_ver=$(ssh -V 2>&1 | grep -oP 'OpenSSH_\K[0-9]+\.[0-9]+')
handle_scp() {
local scp_verion=$1 original_scp="/usr/bin/scp" new_content="/usr/bin/scp.original -T"
if (($(echo "$scp_verion >= 8.7" | bc -l))); then
new_content+=" -O"
fi
mv_file "$original_scp"
write_file "Y" "$original_scp" "$new_content \$*"
chmod 555 "$original_scp"
}
if (($(echo "$scp_ver >= 8.0" | bc -l))); then
handle_scp "$scp_ver"
fi
}
function adapt_gcc() {
local gccbin gccver
gccbin=$(basename "$(readlink -f /usr/bin/gcc)" | sed 's/.*-\(gcc-[0-9]*\)/\1/')
gccver=$(basename "$(readlink -f /usr/bin/gcc)" | awk -F '-' '{print $NF}')
if [[ "$os_type" == "arch" ]]; then
gccbin="x86_64-pc-linux-gnu-gcc"
gccver=100
fi
mv_file /usr/bin/gcc
if (($(echo "$gccver >= 4.6 && $gccver < 7.0" | bc -l))); then
write_file "Y" "/usr/bin/gcc" "#!/bin/bash
/usr/bin/$gccbin -Wl,--no-as-needed \$*"