马哥教育网络班18期+第10周课程练习

博客作业10周.md—E:\Documents

CentOS启动流程

CentOS启动流程

1. 加电自检

通电后主板CMOS中的BIOS(基本输入输出系统)将进行硬件自检并简单设置,根据硬盘等相关设备情况进入下一步

2. 引导加载次序:BOOT Sequence

按次序查找各引导设备,第一个有引导程序的设备即为本次启动用到设备

3. bootloader:

引导加载器,用来引导系统加载的程序

  • windows: ntloader

  • Linux:

    • LILO:LInux LOader

    • GRUB: GRand Uniform Bootloader

    • GRUB 0.X: GRUB Legacy

    • GRUB 1.x: GRUB2

功能:提供一个菜单,允许用户选择要启动系统或不同的内核版本;把用户选定的内核装载到内存中的特定空间中,解压、展开,并把系统控制权移交给内核。

4. GRUB引导加载器

GRUB 是bootloader阶段的引导程序,CentOS主要通过GRUB(GRand Unified Bootloader)引导。

GRUB引导步骤:grub legacy

  • stage1: mbr(磁盘分区表)

  • stage1_5: mbr之后的扇区,让stage1中的bootloader能识别stage2所在的分区上的文件系统;

  • stage2:磁盘分区(/boot/grub/)

    配置文件:/boot/grub/grub.conf <– /etc/grub.conf

stage2内核等通常放置于一个基本磁盘分区;

GRUB的功用

1. 提供菜单、并提供交互式接口  
    e: 编辑模式,用于编辑菜单;  
    c: 命令模式,交互式接口;  
2. 加载用户选择的内核或操作系统  
    允许传递参数给内核  
    可隐藏此菜单  
3. 为菜单提供了保护机制  
    为编辑菜单进行认证  
    为启用内核或操作系统进行认证

常用命令

#help: 获取帮助列表
#help KEYWORD: 详细帮助信息
#find (hd#,#)/PATH/TO/SOMEFILE:
#root (hd#,#)设定grub的根设备
#kernel /PATH/TO/KERNEL_FILE: 设定本次启动时用到的内核文件;额外还可以添加许多内核支持使用的cmdline参数;
#例如:init=/path/to/init, selinux=0
#initrd /PATH/TO/INITRAMFS_FILE: 设定为选定的内核提供额外文件的ramdisk;
#boot: 引导启动选定的内核;

配置文件

[root@node1 ~]# cat /boot/grub/grub.conf 
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /boot/, eg.
#          root (hd0,0)
#          kernel /vmlinuz-version ro root=/dev/mapper/vg_node1-lv_root
#          initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.32-642.1.1.el6.x86_64)
    root (hd0,0)
    kernel /vmlinuz-2.6.32-642.1.1.el6.x86_64 ro root=/dev/mapper/vg_node1-lv_root rd_NO_LUKS rd_LVM_LV=vg_node1/lv_swap rd_NO_MD crashkernel=auto LANG=zh_CN.UTF-8 rd_LVM_LV=vg_node1/lv_root  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
    initrd /initramfs-2.6.32-642.1.1.el6.x86_64.img

常用配置项

default=?: 设定默认启动的菜单项;落单项(title)编号从0开始;
timeout=?:指定菜单项等待选项选择的时长;
splashimage=(hd?,?)/PATH/TO/XPM_PIC_FILE:指明菜单背景图片文件路径;
hiddenmenu:隐藏菜单;
password [--md5] STRING: 菜单编辑认证;
title TITLE:定义菜单项“标题”, 可出现多次;
root (hd?,?):grub查找stage2及kernel文件所在设备分区;为grub的“根”;
kernel /PATH/TO/VMLINUZ_FILE [PARAMETERS]:启动的内核
initrd /PATH/TO/INITRAMFS_FILE: 内核匹配的ramfs文件;
password [--md5] STRING: 启动选定的内核或操作系统时进行认证;

5. 进入Kernel

在GRUB中选择对应的kernel后,kernel会对自身进行初始化

自身初始化

  1. 探测可识别到的所有硬件设备;

  2. 加载硬件驱动程序;(有可能会借助于ramdisk加载驱动)

    ramdisk:内核中的特性之一:使用缓冲和缓存来实现对磁盘上的文件访问

  3. 以只读方式挂载根文件系统;

  4. 运行用户空间的第一个应用程序:/sbin/init

init程序的类型

  • SysV: init, CentOS 5
       配置文件:/etc/inittab

  • Upstart: init, CentOS 6
       配置文件:/etc/inittab, /etc/init/*.conf

  • Systemd:systemd, CentOS 7
       配置文件:/usr/lib/systemd/system, /etc/systemd/system

至此,可以总结为:

POST --> BootSequence (BIOS) --> Bootloader(MBR) --> kernel(ramdisk) --> rootfs(只读) --> init

6. 运行init

CentOS6的init位置为/sbin/init,共分7个级别

运行级别:为了系统的运行或维护等应用目的而设定

0:关机
1:单用户模式(root, 无须登录), single, 维护模式;
2: 多用户模式,会启动网络功能,但不会启动NFS;维护模式;
3:多用户模式,正常模式;文本界面;
4:预留级别;可同3级别;
5:多用户模式,正常模式;图形界面;
6:重启

默认级别:3, 5

切换级别:init ?
例如 init 0 表示关机

[root@node1 ~]# init 0

查看级别
runlevel
who -r

[root@node1 ~]# runlevel
N 3
[root@node1 ~]# who -r
         运行级别 3 2016-06-20 13:12

配置文件:/etc/inittab,CenOS 6的upstart程序配置文件还包括/etc/init/*.conf

配置文件格式为:id:runlevel:action:process
每行定义一个级别

id:指入口标识符,它是一个字符串,对于getty或mingetty等其他login程序项,要求id与tty的编号相同,否则getty程序将不能正常工作。
runlevel:init的系统运行级别
action:是用来定义后面process的运行方式,常用的有下面几种
        wait: 切换至此级别运行一次;
        respawn:此process终止,就重新启动之;
        initdefault:设定默认运行级别;process省略;
        sysinit:设定系统初始化方式,此处一般为指定/etc/rc.d/rc.sysinit
process:为具体的执行程序

下例中,我的配置文件显示为id:3:initdefault:,表示默认运行级别3,即多用户模式的文本界面

[root@node1 ~]# cat /etc/inittab 

# Default runlevel. The runlevels used are:
#   0 - halt (Do NOT set initdefault to this)
#   1 - Single user mode
#   2 - Multiuser, without NFS (The same as 3, if you do not have networking)
#   3 - Full multiuser mode
#   4 - unused
#   5 - X11
#   6 - reboot (Do NOT set initdefault to this)
# 
id:3:initdefault:

设定系统初始化方式时,例如 l3:3:wait:/etc/rc.d/rc 3表示读取 意味着读取/etc/rc.d/rc3.d/下的配置文件

ls /etc/rc.d/rc3.d/
K10saslauthd    S02lvm2-monitor  S12rsyslog           S26udev-post       S99local
K15svnserve     S08ip6tables     S22messagebus        S55sshd
K50netconsole   S08iptables      S25blk-availability  S80postfix
K87restorecond  S10network       S25netfs             S90crond
K89rdisc        S11auditd        S26haldaemon         S99libvirt-guests

说明:

K开头的文件,##运行次序;数字越小,越先运行;数字越小的服务,通常为依赖到别的服务;
S开头的文件,##运行次序;数字越小,越先运行;数字越小的服务,通常为被依赖到的服务;

7. 运行初始化脚本

系统初始化脚本对应的文件是/etc/rc.d/rc.sysinit,会在系统启动时运行一次

[root@node1 ~]# cat /etc/rc.d/rc.sysinit 
#!/bin/bash
#
# /etc/rc.d/rc.sysinit - run once at boot time
#
# Taken in part from Miquel van Smoorenburg's bcheckrc.
#

HOSTNAME=$(/bin/hostname)

set -m

if [ -f /etc/sysconfig/network ]; then
    . /etc/sysconfig/network
fi
if [ -z "$HOSTNAME" -o "$HOSTNAME" = "(none)" ]; then
    HOSTNAME=localhost
fi
#后面省略

主要作用

  1. 设置主机名;

  2. 设置欢迎信息;

  3. 激活udev和selinux;

  4. 挂载/etc/fstab文件中定义的文件系统;

  5. 检测根文件系统,并以读写方式重新挂载根文件系统;

  6. 设置系统时钟;

  7. 激活swap设备;

  8. 根据/etc/sysctl.conf文件设置内核参数;

  9. 激活lvm及software raid设备;

  10. 加载额外设备的驱动程序;

  11. 清理操作;

8.启动系统服务

centos6下的系统服务脚本都放在/etc/rc.d/init.d或者/etc/init.d中,因为建立了链接,所以内容是一样的

[root@node1 ~]ll /etc/init.d
lrwxrwxrwx 1 root root 11 6月  11 22:34 /etc/init.d -> rc.d/init.d
[root@node1 ~]# ls /etc/init.d/
auditd            halt            lvm2-lvmetad  network      sandbox    udev-post
blk-availability  ip6tables       lvm2-monitor  postfix      saslauthd
crond             iptables        messagebus    rdisc        single
functions         killall         netconsole    restorecond  sshd
haldaemon         libvirt-guests  netfs         rsyslog      svnserve

chkconfig命令可以用来查看服务在所有级别的启动或关闭设定情形:chkconfig [--list] [name]

查看chkconfig –list

[root@node1 ~]# chkconfig --list
auditd          0:关闭    1:关闭    2:启用    3:启用    4:启用    5:启用    6:关闭
blk-availability    0:关闭    1:启用    2:启用    3:启用    4:启用    5:启用    6:关闭
crond           0:关闭    1:关闭    2:启用    3:启用    4:启用    5:启用    6:关闭
haldaemon       0:关闭    1:关闭    2:关闭    3:启用    4:启用    5:启用    6:关闭
ip6tables       0:关闭    1:关闭    2:启用    3:启用    4:启用    5:启用    6:关闭
iptables        0:关闭    1:关闭    2:启用    3:启用    4:启用    5:启用    6:关闭

9. 设置登陆终端

根据终端配置打印登陆提示符

初始化阶段总结为

/sbin/init --> (/etc/inittab) --> 设置默认运行级别 --> 运行系统初始脚本、完成系统初始化 --> 关闭对应下需要关闭的服务,启动需要启动服务 --> 设置登录终端

整体总结

POST --> Boot Sequence(BIOS) --> Boot Loader (MBR) --> Kernel(ramdisk) --> rootfs --> switchroot --> /sbin/init -->(/etc/inittab, /etc/init/*.conf) --> 设定默认运行级别 --> 系统初始化脚本 --> 关闭或启动对应级别下的服务 --> 启动终端

习题

习题1

为运行于虚拟机上的CentOS 6添加一块新硬件,提供两个主分区;
 (1) 为硬盘新建两个主分区;并为其安装grub;
 (2) 为硬盘的第一个主分区提供内核和ramdisk文件; 为第二个分区提供rootfs;
 (3) 为rootfs提供bash、ls、cat程序及所依赖的库文件;
 (4) 为grub提供配置文件;
 (5) 将新的硬盘设置为第一启动项并能够正常启动目标主机;

查询磁盘情况

    [root@node1 ~]# fdisk -l /dev/sd[a-z]
   
    Disk /dev/sdb: 21.5 GB, 21474836480 bytes
    255 heads, 63 sectors/track, 2610 cylinders
    Units = cylinders of 16065 * 512 = 8225280 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x00000000

磁盘分区并格式化

[root@node1 ~]# fdisk /dev/sdb


[root@node1 ~]# partx -a /dev/sdb
BLKPG: Device or resource busy
error adding partition 1
BLKPG: Device or resource busy
error adding partition 2
[root@node1 ~]# cat /proc/partitions 
major minor  #blocks  name

   8        0   20971520 sda
   8        1     512000 sda1
   8        2   20458496 sda2
   8       16   20971520 sdb
   8       17     112423 sdb1
   8       18    5253255 sdb2
 253        0    6144000 dm-0
 253        1    2031616 dm-1
 253        2    4087808 dm-2
 253        3    8192000 dm-3


[root@node1 ~]# mke2fs -t ext4 /dev/sdb1


[root@node1 ~]# mke2fs -t ext4 /dev/sdb2

创建目录并挂载分区

[root@node1 ~]# mkdir /mnt/boot /mnt/sysroot
[root@node1 ~]# ls /mnt
boot  sysroot
[root@node1 ~]# mount /dev/sdb1 /mnt/boot/
[root@node1 ~]# mount /dev/sdb2 /mnt/sysroot/
[root@node1 ~]# ls /mnt/boot
lost+found
[root@node1 ~]# ls /mnt/sysroot/
lost+found

拷贝kernel和ramfs文件

[root@node1 ~]# cp /boot/initramfs-2.6.32-642.1.1.el6.x86_64.img /mnt/boot/initramfs.img
[root@node1 ~]# cp /boot/vmlinuz-2.6.32-642.1.1.el6.x86_64 /mnt/boot/vmlinuz
[root@node1 ~]# ls /mnt/boot/
initramfs.img  lost+found  vmlinuz

安装grub

[root@node1 boot]# grub-install --root-directory=/mnt /dev/sdb
Probing devices to guess BIOS drives. This may take a long time.
Installation finished. No error reported.
This is the contents of the device map /mnt/boot/grub/device.map.
Check if this is correct or not. If any of the lines is incorrect,
fix it and re-run the script `grub-install'.

(fd0)   /dev/fd0
(hd0)   /dev/sda
(hd1)   /dev/sdb

创建根目录并拷贝指定程序

[root@node1 ~]# cd /mnt/sysroot/
[root@node1 sysroot]# mkdir -pv bin sbin boot root home usr etc var tmp lib lib64 proc dev mnt media
[root@node1 sysroot]# ls
bin   dev  home  lib64       media  proc  sbin  usr
boot  etc  lib   lost+found  mnt    root  tmp   var
[root@node1 sysroot]# cp /bin/bash /bin/ls /bin/cat /mnt/sysroot/bin/

拷贝库文件

[root@node1 bin]# ldd /bin/bash
    
[root@node1 bin]# cp /lib64/libtinfo.so.5 /mnt/sysroot/lib64/
[root@node1 bin]# cp /lib64/libdl.so.2 /mnt/sysroot/lib64/
[root@node1 bin]# cp /lib64/libc.so.6 /mnt/sysroot/lib64/
[root@node1 bin]# cp /lib64/ld-linux-x86-64.so.2 /mnt/sysroot/lib64/
[root@node1 bin]# ldd /bin/ls
[root@node1 bin]# cp /lib64/libselinux.so.1 /mnt/sysroot/lib64/
[root@node1 ~]# cp /lib64/librt.so.1 /mnt/sysroot/lib64/
[root@node1 bin]# cp /lib64/libcap.so.2 /mnt/sysroot/lib64/
[root@node1 bin]# cp /lib64/libacl.so.1 /mnt/sysroot/lib64/
[root@node1 bin]# cp /lib64/libpthread.so.0 /mnt/sysroot/lib64/
[root@node1 bin]# cp /lib64/libattr.so.1 /mnt/sysroot/lib64/
[root@node1 bin]# ldd /bin/cat

修改grub配置文件

[root@node1 ~]# vim /mnt/boot/grub/grub.conf 

default=0
timeout=5
title CentOS (Express)
    root (hd0,0)
    kernel /vmlinuz ro root=/dev/sda2 selinux=0 init=/bin/bash
    initrd /initramfs.img

关闭用来设置的虚拟机,将硬盘加载到新虚拟机后,正常启动bash,并能执行ls和cat命令

习题2

制作一个kickstart文件以及一个引导镜像。描述其过程。

anaconda的配置方式

(1) 交互式配置方式;
(2) 通过读取事先给定的配置文件自动完成配置;
   按特定语法给出的配置选项;
       kickstart文件;

安装引导选项

text: 文本安装方式
method: 手动指定使用的安装方法
与网络相关的引导选项:

ip=IPADDR
netmask=MASK
gateway=GW
dns=DNS_SERVER_IP
ifname=NAME:MAC_ADDR

与远程访问功能相关的引导选项

vnc
vncpassword='PASSWORD'

指明kickstart文件的位置

ks=
    DVD drive: ks=cdrom:/PATH/TO/KICKSTART_FILE
    Hard drive: ks=hd:/device/drectory/KICKSTART_FILE
    HTTP server: ks=http://host:port/path/to/KICKSTART_FILE
    FTP server: ks=ftp://host:port/path/to/KICKSTART_FILE
    HTTPS server: ks=https://host:port/path/to/KICKSTART_FILE

启动紧急救援模式

rescue

kickstart文件的格式
命令段:指明各种安装前配置,如键盘类型等;
程序包段:指明要安装的程序包组或程序包,不安装的程序包等;

%packages
@group_name
package
-package
%end

脚本段

%pre: 安装前脚本
    运行环境:运行于安装介质上的微型Linux环境

%post: 安装后脚本
    运行环境:安装完成的系统;

命令段中的命令
必备命令

authconfig: 认证方式配置
    authconfig --useshadow  --passalgo=sha512
bootloader:bootloader的安装位置及相关配置
    bootloader --location=mbr --driveorder=sda --append="crashkernel=auto crashkernel=auto rhgb rhgb quiet quiet"
keyboard: 设定键盘类型
lang: 语言类型
part: 创建分区
rootpw: 指明root的密码
timezone: 时区

可选命令

install OR upgrade
text: 文本安装界面
network
firewall
selinux
halt
poweroff
reboot
repo
user:安装完成后为系统创建新用户
url: 指明安装源

创建kickstart文件的方式
   (1) 直接手动编辑;
       依据某模板修改;
   (2) 可使用创建工具:system-config-kickstart (CentOS 6)
       依据某模板修改并生成新配置;

检查ks文件的语法错误:ksvalidator
   # ksvalidator /PATH/TO/KICKSTART_FILE

创建引导光盘
   # mkisofs -R -J -T -v &ndash;no-emul-boot &ndash;boot-load-size 4 &ndash;boot-info-table -V &ldquo;CentOS 6.8 x86_64 boot&rdquo; -b isolinux/isolinux.bin -c isolinux/boot.cat -o /root/boot.iso myiso/

习题3

写一个脚本
 (1) 能接受四个参数:start, stop, restart, status
  start: 输出“starting 脚本名 finished.”
  &hellip;
 (2) 其它任意参数,均报错退出;

#!/bin/bash
#
# chkconfig: - 88 12
# description: test service script
#
prog=$(basename $0)
lockfile=/var/lock/subsys/$prog

start() {
    if [ -e $lockfile ]; then
    echo "$prog is aleady running."
    return 0
    else
    touch $lockfile
    [ $? -eq 0 ] && echo "Starting $prog finished."
    fi
}

stop() {
    if [ -e $lockfile ]; then
    rm -f $lockfile && echo "Stop $prog ok."
    else
    echo "$prog is stopped yet."
    fi
}

status() {
    if [ -e $lockfile ]; then
    echo "$prog is running."
    else
    echo "$prog is stopped."
    fi
}

usage() {
    echo "Usage: $prog {start|stop|restart|status}"
}

if [ $# -lt 1 ]; then
    usage
    exit 1
fi

if [ $1 != 'start' -a $1 !='stop' -a  $1 != 'restart' -a $1 != 'status' ];then
    usage
    exit 2
fi

case $1 in
start)
    start
    ;;
stop)
    stop
    ;;
restart)
    stop
    start
    ;;
status)
    status
    ;;
*)
    usage
esac

习题4

写一个脚本,判断给定的用户是否登录了当前系统;
 (1) 如果登录了,则显示用户登录,脚本终止;
 (2) 每3秒钟,查看一次用户是否登录;

#!/bin/bash
#
read -p "Enter a user name: " username
while true; do
    if who | grep "^$username" &> /dev/null; then
        break
    fi
    sleep 3
done

echo "$username logged on."

习题5

写一个脚本,显示用户选定要查看的信息;
  cpu) display cpu info
  mem) display memory info
  disk) display disk info
  quit) quit
  非此四项选择,则提示错误,并要求用户重新选择,只到其给出正确的选择为止;

#!/bin/bash
#
cat << EOF
cpu) show cpu information;
mem) show memory information;
disk) show disk information;
quit) quit
============================
EOF

read -p "Enter a option: " option
while [ "$option" != 'cpu' -a "$option" != 'mem' -a "$option" != 'disk' -a "$option" != 'quit' ]; do
    read -p "Wrong option, Enter again: " option
done

case "$option" in
cpu)
    lscpu
    ;;
mem)
    cat /proc/meminfo
    ;;
disk)
    fdisk -l
    ;;
*)
    echo "Quit..."
    exit 0
    ;;
esac

习题6

写一个脚本
 (1) 用函数实现返回一个用户的UID和SHELL;用户名通过参数传递而来;
 (2) 提示用户输入一个用户名或输入“quit”退出;
   当输入的是用户名,则调用函数显示用户信息;
   当用户输入quit,则退出脚本;进一步地:显示键入的用户相关信息后,再次提醒输出用户名或quit:

#!/bin/bash
#
function getinfo {

if id $op &> /dev/null;then
    grep -E '^('$op')\>' /etc/passwd | cut -d: -f1,3,7;read -p "Enter a username or quit:" op
else 
    read -p  "wrong argument,plsease enter a username or quit:" op
fi
}

read -p "Enter a username or quit:" op
while [[ $op != "quit" ]];do
    getinfo $op
done

练习7

写一个脚本,完成如下功能(使用函数)
  (1) 提示用户输入一个可执行命令的名字;获取此命令依赖的所有库文件;
  (2) 复制命令文件至/mnt/sysroot目录下的对应的rootfs的路径上,例如,如果复制的文件原路径是/usr/bin/useradd,则复制到/mnt/sysroot/usr/bin/目录中;
  (3) 复制此命令依赖的各库文件至/mnt/sysroot目录下的对应的rootfs的路径上;规则同上面命令相关的要求;

#!/bin/bash
read -p "Enter a exeable commond:" cmd
path() {
	 whereis $cmd | cut -d' ' -f2
}
ldd $(path $1)| sed '1d'| grep -Eo "/.*[0-9] " > path.txt
cp $(path $1) /mnt/sysroot$(path $1)
while read line;do
	cp $line /mnt/sysroot$line
	done < ./path.txt

原创文章,作者:sthwrong,如若转载,请注明出处:http://www.178linux.com/19012

(0)
sthwrongsthwrong
上一篇 2016-06-23
下一篇 2016-06-23

相关推荐

  • TIME_WAIT引起Cannot assign requested address报错

    1.  问题描述      有时候用redis客户端(php或者java客户端)连接Redis服务器,报错:“Cannot assign requested address。”      原因是客户端频繁的连接服务器,由于每次连接都在很短时间内结束,导致很多的TIME_WAIT。所以新的连…

    Linux干货 2016-03-09
  • 第九周

    1、写一个脚本,判断当前系统上所有用户的shell是否为可登录shell(即用户的shell不是/sbin/nologin);分别这两类用户的个数;通过字符串比较来实现;   1 #!/bib/bash   2 #   3 a=0   4 x=0   5 y=…

    Linux干货 2017-05-25
  • 马哥教育网络21期+第二周练习博客

    1、Linux上的文件管理类命令都有哪些,其常用的使用方法及其相关示例演示。 长用的文件管理类命令有cp(复制),mv(移动),rm(删除)。接下来我将为大家一一讲解。 复制命令:cp 在cp时要根据源和目的做出确认与调整; 命令格式:     cp [OPTION]… [-T] SO…

    Linux干货 2016-07-22
  • 从Linux小白到大牛——与狼共舞的日子2

    马哥教育网络班21期+第2周课程练习 1、Linux上的文件管理类命令都有哪些,其常用的使用方法及其相关示例演示。 cp:copy,复制文件 cp SRC DEST   SRC为文件     如果目录不存在:新建DEST,并将SRC中内容填充至DEST中     如果目…

    Linux干货 2016-07-17
  • 用户管理、三种权限、三种特殊权限的使用

    用户管理、三种权限、三种特殊权限的使用 一、用户管理 1、软链接:ln  -s  相对于软链接的路径/绝对路径   软链接文件    硬链接:ln  相对路径原文件   硬链接文件 2、getent的使用    gentent p…

    系统运维 2016-08-05
  • LAMP组合的编译安装(apache2.4+mariadb5.5+php5.6)

    安装次序 httpd, MariaDB, php 安装apache2.4 [root@root ~]# yum groupinstall "Development Tools" "Server Platform Develoment "&n…

    Linux干货 2016-06-29

评论列表(1条)

  • 马哥教育
    马哥教育 2016-06-23 14:15

    写的很棒,但是有的脚本应该有点小瑕疵,有的还可以在完善一下