9一、題目要求 : 部署MySQL主從mysql
用shell腳本實現,部署mysql主從,假設兩臺機器上已經安裝了mysql,而且目前無新庫。
linux
【核心要點】git
步驟 : 一、主上改配置文件,打開bin-log,設定server_id ,設定ignore_db ,重啓,受權用戶,鎖表,show master staus .github
二、從上改配置文件,設定server_id,重啓,stop slave ,chang master ,start slave。sql
在主上寫一個腳本,全部操做在此腳本完成,包括寫expect腳本和執行expect腳本。docker
#!/bin/bash #這個腳本用來配置MySQL主從同步 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-17 #!/bin/bash master_ip=192.168.100.12 slave_ip=192.168.100.13 mysqlc="mysql -uroot -paminglinux" check_ok() { if [ $? -ne 0 ] then echo "$1 出錯了。" exit 1 fi } f_exist() { d=`date +%F%T` if [ -f $1 ] then mv $1 $1_$d fi } ## 設置主mysql配置 if ! grep '^server-id' /etc/my.cnf then sed -i '/^\[mysqld\]$/a\server-id = 1001' /etc/my.cnf fi if ! grep '^log-bin.*=.*' /etc/my.cnf then sed -i '/^\[mysqld\]$/a\log-bin = aminglinux' /etc/my.cnf fi sed -i '/^log-bin.*/a\binlog-ignore-db = mysql ' /etc/my.cnf /etc/init.d/mysqld restart check_ok "主上重啓mysql" ## 登陸mysql,受權用戶、鎖表以及show master status。 $mysqlc <<EOF grant replication slave on *.* to 'repl'@$slave_ip identified by 'yourpassword'; flush tables with read lock; EOF $mysqlc -e "show master status" > /tmp/master.log file=`tail -1 /tmp/master.log|awk '{print $1}'` pos=`tail -1 /tmp/master.log|awk '{print $2}'` ## 建立在從上配置和操做的腳本 f_exist /tmp/slave.sh cat > /tmp/slave.sh << EOF #!/bin/bash if ! grep '^server-id' /etc/my.cnf then sed -i '/^\[mysqld\]$/a\server-id = 1002' /etc/my.cnf fi /etc/init.d/mysqld restart check_ok "從上重啓mysql" $mysqlc <<EOF stop slave; change master to master_host="$master_ip", master_user="repl", master_password="yourpassword", master_log_file="$file", master_log_pos=$pos; start slave; EOF EOF ## 建立傳輸slave.sh的expect腳本 f_exist /tmp/rs_slave.expect cat > /tmp/rs_slave.expect <<EOF #!/usr/bin/expect set passwd "aminglinux" spawn rsync -a /tmp/slave.sh root@$slave_ip:/tmp/slave.sh expect { "yes/no" { send "yes\r"} "password:" { send "\$passwd\r" } } expect eof EOF ## 執行expect腳本 chmod +x /tmp/rs_slave.expect /tmp/rs_slave.expect check_ok "傳輸slave.sh" ## 建立遠程執行命令的expect腳本 f_exist /tmp/exe.expect cat > /tmp/exe.expect <<EOF #!/usr/bin/expect set passwd "aminglinux" spawn ssh root@$slave_ip expect { "yes/no" { send "yes\r"} "password:" { send "\$passwd\r" } } expect "]*" send "/bin/bash /tmp/slave.sh\r" expect "]*" send "exit\r" EOF ## 執行expect腳本 chmod +x /tmp/exe.expect /tmp/exe.expect check_ok "遠程執行slave.sh" ## 主上解鎖表 $mysqlc -e "unlock tables"
實例 :shell
在/etc/my.cnf文件中,添加server-id數據庫
執行腳本,查看結果bash
注意 : 服務器
if [ $? -ne 0 ] #$?等於0
if ! grep '^server-id' /etc/my.cnf #在/etc/my.cnf文件中查看有沒有server-id,若是沒有,執行下一步。
sed -i '/^\[mysqld\]$/a\server-id = 1001' /etc/my.cnf #/etc/my.cnf文件中查看沒有server-id,就在/etc/my.cnf 中添加。
sed -i '/^\[mysqld\]$/a\log-bin = aminglinux' /etc/my.cnf #
sed -i '/^log-bin.*/a\binlog-ignore-db = mysql ' /etc/my.cnf #添加一個忽略的數據庫叫MySQL,不作同步。
sed -i '/^\[mysqld\]$/a\server-id = 1002' /etc/my.cnf #將server-id = 1002,輸入到/etc/my.cnf 。
$mysqlc -e "show master status" > /tmp/master.log #show master statu的結果,輸出到 /tmp/master.log 。
EOF #是用在mysqlc
EOF #是用在cat > /tmp/slave.sh << EOF
spawn rsync -a /tmp/slave.sh root@$slave_ip:/tmp/slave.sh #將/tmp/slave.sh傳輸到root@$slave_ip:/tmp/slave.sh
若是系統是CentOS 7,並且使用的yum安裝的MySQL,重啓命令可能要使用 : systemctl restart mysqld
9二、題目要求 : 管理docker
寫一個腳本,實現一鍵管理docker容器,好比啓動、關閉、刪除容器等操做。 要求:
【核心要點】
一、要關閉或啓動容器,首先要知道容器的id,使用命令docker ps -a 查看,第一列就是容器id。
二、須要以交互的方式讓用戶輸入關閉、啓動或者刪除的命令,若是用戶輸入的命令不對須要給出提示。
三、能夠把容器的id先存入到一個臨時文件裏,方便後續遍歷。
#!/bin/bash #這個腳本用來管理docker容器 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-17 while true do read -p "請輸入你要執行的操做:(stop/start/rm) " opt if [ -z "$opt" ] then echo "請輸入要執行的操做。" continue else break fi done docker ps -a |awk '{print $1}' > /tmp/id.txt case $opt in stop) for id in `cat /tmp/id.txt` do docker stop $id done ;; start) for id in `cat /tmp/id.txt` do docker start $id done rm) for id in `cat /tmp/id.txt` do read -p "將要刪除容器$id,是否繼續?(y|n)" c case $c in y|Y) docker rm -f $id ;; n|N) echo "容器$id不會被刪除。" ;; *) echo "你只能輸入'y'或者'n'。" ;; esac done *) echo "你只能輸入start/stop/rm。" ;; esac
注意 :
docker ps -a |awk '{print $1}' > /tmp/id.txt # 把全部的容器的id,寫入到/tmp/id.txt
for id in `cat /tmp/id.txt` # 在 /tmp/id.txt,查看容器的ID。
9三、題目要求 : 安裝配置samba
寫個shell腳本,可以實現一鍵安裝並配置samba服務,執行該腳本時須要帶一個參數,爲共享的目錄,目錄若不存在,需自動建立。
要求,任何人均可以訪問,且不用密碼,而且目錄是隻讀的。
【核心要點】
一、須要判斷用戶給出的目錄是否是絕對路徑,即是不是'/'開頭
二、腳本要判斷samba服務是否已經安裝,若已經安裝了就不須要執行yum install samba了
#!/bin/bash #這個腳本用來一鍵安裝並配置samba #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-17 if [ "$#" -ne 1 ] then echo "運行腳本的格式爲:$0 /dir/" exit 1 else if ! echo $1 |grep -q '^/.*' then echo "請提供一個絕對路徑。" exit 1 fi fi if ! rpm -q samba >/dev/null then echo "將要安裝samba" sleep 1 yum install -y samba if [ $? -ne 0 ] then echo "samba安裝失敗" exit 1 fi fi cnfdir="/etc/samba/smb.conf" cat >> $cnfdir <<EOF [share] comment = share all path = $1 browseable = yes public = yes writable = no EOF if [ ! -d $1 ] then mkdir -p $1 fi chmod 777 $1 echo "test" > $1/test.txt #假設系統爲CentOS7 systemctl start smb if [ $? -ne 0 ] then echo "samba服務啓動失敗,請檢查配置文件是否正確。" else echo "samba配置完畢,請驗證。" fi
實例 :
執行腳本,查看結果
注意 :
if ! echo $1 |grep -q '^/.*' #若是不是/開頭,就提示用戶提供一個絕對路徑。
if [ $? -ne 0 ] # 當$?不等於0,提示安裝失敗了。
cat >> $cnfdir <<EOF #追加幾行下面的內容
[share] #模塊的名字 [share]
comment = share all #comment(描述)
path = $1 # 共享的目錄路徑
browseable = yes #是否是可見的
public = yes #是否是公開的,意思是不須要密碼認證。
writable = no #是否是可寫的
if [ ! -d $1 ] #判斷目錄是否存在。
echo "test" > $1/test.txt #在$1下,建立一個文件test.txt
9四、題目要求 : 批量查看墮胎機器負載
假如公司的一個業務,域名爲www.aminglinux.com,如今有5臺機器在跑。爲了快速查看這5臺機器的負載,須要你寫一個Shell腳本,運行腳本後,就能一會兒把5臺機器的負載所有打印出來。
【核心要點】
expect腳本或者配置密鑰認證
ssh-keygen -f /root/.ssh/newkey #把公鑰拷貝到,對方的文件的目錄下 ;-f指定目錄的名字
ssh -i /root/.ssh/newkey ip #指定私鑰的位置。
ssh-agent #把私鑰搞到內存裏面
ssh-add /root/.ssh/newkey #把密鑰添加到內存中。
eval ‘ssh-agent’ #
#!/bin/bash #這個腳本用來批量查機器負載 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-17 for ip in `cat /tmp/ip.list` do echo $ip ssh $ip "uptime" done
實例 :
把密鑰寫到/tmp/aaa文件中
ls /tmp/查看生成的密鑰,aaa是私鑰,aaa.pub是公鑰
測試,查看拷貝的密鑰,第一次登陸127.0.0.1,有沒有生效。
若是出現下面的提示,說明沒有添加成功,密鑰生效,就把cat /tmp/aaa.pub中的公密鑰寫入到vi /root/.ssh/authorized_keys。再次執行ssh -i /tmp/aaa root@127.0.0.1
第二次登陸127.0.0.1的效果。
ssh-agent把私鑰搞到內存裏面
再次執行發現就不用,密碼登陸了。
執行腳本,查看結果
注意 :
9五、題目要求 : 自動掛雲盤
咱們使用的雲主機,購買一塊雲盤後,默認並非掛載狀態的,用shell寫一個腳本,只要把盤符和掛載點以參數的形式提供給腳本,該腳本就能夠自動格式化、掛載。
要求:
【核心要點】
一、參數要有兩個,第一個是設備名,第二個是掛載點,須要判斷給出的參數個數以及是否可用
二、格式化磁盤的命令爲mkfs.ext4磁盤設備名。
三、mount命令掛載,掛載完後還須要編輯/etc/fstab配置文件
#!/bin/bash #這個腳本用來自動掛載磁盤 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-17 if [ $# -ne 2 ] then echo "Useage $0 盤符 掛載點, 如: $0 /dev/xvdb /data" exit 1 fi if [ ! -b $1 ] then echo "你提供的盤符不正確,請檢查後再操做" exit 1 fi echo "格式化$1" mkfs -t ext4 $1 if [ ! -d $2 ] ;then mkdir -p $2 fi n=`awk '$NF == "$2"' /etc/fstab|wc -l` if [ $n -eq 0 ] then echo "$1 $2 ext4 defaults 0 0" >> /etc/fstab mount -a else echo "配置文件/etc/fstab中已經存在掛載點$2,請檢查一下." exit 1 fi
實例 :
執行腳本,查看結果
注意 :
9六、題目要求 : 併發備份數據庫
需求背景:
領導要求小明備份數據庫服務器裏面的100個庫(數據量在幾十到幾百G),須要以最快的時間完成(5小時內),而且不能影響服務器性能。
【核心要點】
#!/bin/bash #這個腳本用來併發備份數據庫 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-19 ##假設100個庫的庫名、host、port以及配置文件路徑存到了一個文件裏,文件名字爲/tmp/databases.list ##格式:db1 10.10.10.2 3308 /data/mysql/db1/my.cnf ##備份數據庫使用xtrabackup(因爲涉及到myisam,命令爲inoobackupex) exec &> /tmp/mysql_bak.log if ! which innobackupex &>/dev/nll then echo "安裝xtrabackup工具" rpm -ivh http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm && \ yum install -y percona-xtrabackup-24 if [ $? -ne 0 ] then echo "安裝xtrabackup工具出錯,請檢查。" exit 1 fi fi bakdir=/data/backup/mysql bakuser=vyNctM bakpass=99omeaBHh function bak_data { db_name=$1 db_host=$2 db_port=$3 cnf=$4 [ -d $bakdir/$db_name ] || mkdir -p $bakdir/$db_name innobackupex --defaults-file=$4 --host=$2 --port=$3 --user=$bakuser --password=$bakpass $bakdir/$1 if [ $? -ne 0 ] then echo "備份數據庫$1出現問題。" fi } fifofile=/tmp/$$ mkfifo $fifofile exec 1000<>$fifofile thread=10 for ((i=0;i<$thread;i++)) do echo >&1000 done cat /tmp/databases.list | while read line do #每循環一次,讀一次fd100中的內容,即空行,只有讀到空行了纔會執行{}內的指令 #每次循環都須要打印當前的時間,休眠1秒,而後再次向fd100中寫入空行,這樣後續的read就有內容了 # read -u1000 { bak_data `echo $line` echo >&1000 } & //丟到後臺去,這樣10次很快就循環完,只不過這些任務是在後臺跑着,因爲咱們一開始就向fd1000裏寫入了兩個空行,因此read會一次性讀到兩行。 done #等待全部後臺任務執行完成 wait #刪除fd1000 exec 1000>&- #刪除命名管道 rm -f $fifofile
實例 :
安裝一個窗口screen , 直接輸入」screen「命令就進入了另外一個窗口
使用mkfifo命令,建立一個管道文件1.fifo。
往管道里面寫入東西,出現卡頓現象,緣由:只寫入東西,沒有進程讀它。先使用"cat 1.fifo"讀取新建的管道文件,而後再寫入東西。(ctrl +a 退出screen窗口)
把100個文件流綁定再一塊兒,並查看結果,生成的結果是一個軟連接。
讀100個用戶,並賦值給a。
注意 :
exec &> /tmp/mysql_bak.log #定義一個/tmp/mysql_bak.log ,全部的命令、結果寫入到這個日誌裏面
if ! which innobackupex &>/dev/nll # 檢測innobackupex命令是否存在
function bak_data { #定義備份數據庫的函數,用於備份數據庫
innobackupex --defaults-file=$4 --host=$2 --port=$3 --user=$bakuser --password=$bakpass $bakdir/$1 #備份數據庫,$4指定配置文件的路徑等等,而後放到 $bakdir/$1
if [ $? -ne 0 ] #返回值不等於0,就提示用戶。
fifofile=/tmp/$$ #fifo文件的定義
mkfifo $fifofile #建立匿名管道文件
exec 1000<>$fifofile #把100個文件流綁定再一塊兒。
thread=10 #定義併發量爲10
echo >&1000 #寫入10次
cat /tmp/databases.list | while read line #有幾個數據庫的列表,就循環幾回。
9七、題目要求 : 打印三角形
以前我們打印過正方形,也打印過乘法口訣,那今天來打印一個三角形(正三角形,元素用*表示)。
【核心要點】
正三角形的元素排列,若是邊長爲5個* ,在shell終端顯示該正三角形的話,須要有5行,第一行應該先打印4個空格,而後再打印'*',第二行先打印3個空格,而後打印‘*’ ,一直到第5行打印0個空格。
#!/bin/bash #這個腳本用來打印三角形 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-19 while true do read -p "please input the lenth: " n if [ -z $n ] then echo "要輸入一個數字。" continue else n1=`echo $n|sed 's/[0-9]//g'` if [ -n "$n1" ] then echo "你輸入的不是純數字,從新輸入。" continue else break fi fi done for i in `seq 1 $n` do j=$[$n-$i] for m in `seq $j` do echo -n " " done for p in `seq 1 $i` do echo -n "* " done echo done
實例 :
執行腳本,輸入執行三角形的邊長爲幾,查看結果。
注意 :
if [ -z $n ] #$n爲空,提示用戶。
n1=`echo $n|sed 's/[0-9]//g'` #判斷用戶輸入的,是否是數字。
if [ -n "$n1" ] #若是不是數字。就提示用戶。是數字就退出。
for i in `seq 1 $n` #循環次數是1到$n.
j=$[$n-$i] #第一次打印的空格次數嗎,j是要打印空格的次數。
9八、題目要求 : 截取字符串
利用你學過的知識點,想辦法根據要求。
字符串var=http://www.aaa.com/root/123.htm
1.取出www.aaa.com/root/123.htm
2.取出123.htm
4.取出http:
5.取出http://
6.取出root/123.htm
7.取出123
【核心要點】
grep/sed/awk
#!/bin/bash #這個腳本用來截取字符串 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-19 var=http://www.aaa.com/root/123.htm echo "1.取出www.aaa.com/root/123.htm" echo $var |awk -F '//' '{print $2}' echo "2.取出123.htm" echo $var |awk -F '/' '{print $5}' echo "3.取出http://www.aaa.com/root" echo $var |sed 's#/123.htm##' echo "4.取出http:" echo $var |awk -F '//' '{print $1}' echo "5.取出http://" echo $var |awk -F 'www' '{print $1}' echo "6.取出root/123.htm" echo $var |awk -F 'com/' '{print $2}' echo $var |awk -F '/' '{print $4"/"$5}' echo "7.取出123" echo $var |sed 's/[^0-9]//g'
實例 :
使用awk命令截取出www.aaa.com/root/123.htm
使用sed命令截取出第二段字符
使用awk命令截取出取出123.htm、取出http://www.aaa.com/root、取出http:、取出http://、取出root/123.htm、取出123。-F表示以什麼作空格、間隔符,
執行腳本,查看結果
9九、題目要求 : 修改文本格式
請把下面的字符串寫入到test3.txt文檔中:
zhangsan y97JbzPru lisi 5JhvCls6q xiaowang Nnr8qt2Ma laoma iqMtvC02y zhaosi 9fxrb4sJD
改成以下:
zhangsan:y97JbzPru lisi:5JhvCls6q xiaowang:Nnr8qt2Ma laoma:iqMtvC02y zhaosi:9fxrb4sJD
【核心要點】
奇數、偶數行
#!/bin/bash #這個腳本用來格式化文本 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-19 n=`wc -l test3.txt|awk '{print $1}'` n2=$[$n/2] for i in `seq 1 $n2` do i2=$[$i*2] j=$[$i2-1] l1=`sed -n "$i2"p test3.txt` l2=`sed -n "$j"p test3.txt` echo $l2:$l1 done
實例 :
把第一行的第二行的換行符換成冒號。;s表示替換,N表示 把第一二變成一行; \n表示 表示替換; :/ :把換行符換成冒號。
執行腳本,查看結果
注意 :
n=`wc -l test3.txt|awk '{print $1}'` #統計文檔中的行數。並打印出一行
n2=$[$n/2] #把第二行,合併成一行
for i in `seq 1 $n2` #執行的行數是1到$n2
i2=$[$i*2] #i2表示 ,須要要換行的次數
j=$[$i2-1] #j表示 ,循環的次數
l1=`sed -n "$i2"p test3.txt` #l1表示奇數行的內容,
l2=`sed -n "$j"p test3.txt` #l2表示偶數行的內容,
echo $l2:$l1 #$l2:$l1 表示偶數行、奇數行合併的行數
100、題目要求 : 自定義rm
inux系統的rm命令太危險,一不當心就會刪除掉系統文件。 寫一個shell腳原本奇數行的,要求當刪除一個文件或者目錄時,都要作一個備份,而後再刪除。下面分兩種狀況,作練習:
假設有一個大的分區/data/,每次刪除文件或者目錄以前,都要先在/data/下面建立一個隱藏目錄,以日期/時間命名,好比/data/.201703271012/,而後把全部刪除的文件同步到該目錄下面,可使用rsync -R 把文件路徑一塊兒同步
不知道哪一個分區有剩餘空間,在刪除以前先計算要刪除的文件或者目錄大小,而後對比系統的磁盤空間,若是夠則按照上面的規則建立隱藏目錄,並備份,若是沒有足夠空間,要提醒用戶沒有足夠 的空間備份並提示是否放棄備份,若是用戶選擇y,則直接刪除文件或者目錄,若是選擇n,則提示未刪除,而後退出腳本。
【核心要點】
1. 簡單 #!/bin/bash #這個腳本用來自定義rm #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-19 filename=$1 big_filesystem=/data/ if [ ! -e $1 ] then echo "$1 不存在,請使用絕對路徑" exit fi d=`date +%Y%m%d%H%M` read -p "Are U sure delete the file or directory $1? y|n: " c case $c in y|Y) mkdir -p $big_filesystem/.$d && rsync -aR $1 $big_filesystem/.$d/$1 && /bin/rm -rf $1 ;; n|N) exit 0 ;; *) echo "Please input 'y' or 'n'." ;; esac 2.複雜 #!/bin/bash #這個腳本用來自定義rm #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-19 #!/bin/bash filename=$1 if [ ! -e $1 ] then echo "$1 不存在,請使用絕對路徑" exit fi d=`date +%Y%m%d%H%M` f_size=`du -sk $1|awk '{print $1}'` disk_size=`LANG=en; df -k |grep -vi filesystem|awk '{print $4}' |sort -n |tail -n1` big_filesystem=`LANG=en; df -k |grep -vi filesystem |sort -n -k4 |tail -n1 |awk '{print $NF}'` if [ $f_size -lt $disk_size ] then read -p "Are U sure delete the file or directory: $1? y|n: " c case $c in y|Y) mkdir -p $big_filesystem/.$d && rsync -aR $1 $big_filesystem/.$d/$1 && /bin/rm -rf $1 ;; n|N) exit 0 ;; *) echo "Please input 'y' or 'n'." ;; esac else echo "The disk size is not enough to backup the files $1." read -p "Do you want to delete $1? y|n: " c case $c in y|Y) echo "It will delete $1 after 5 seconds whitout backup." for i in `seq 1 5`; do echo -ne ". "; sleep 1;done echo /bin/rm -rf $1 ;; n|N) echo "It will not delete $1." exit 0 ;; *) echo "Please input 'y' or 'n'." ;; esac fi
實例 :
查看磁盤的使用率
執行腳本,查看結果
注意 :
if [ ! -e $1 #若是提供的路徑不存在,就提示用戶。
mkdir -p $big_filesystem/.$d && rsync -aR $1 $big_filesystem/.$d/$1 && /bin/rm -rf $1 #建立隱藏的目錄,並備份隱藏的目錄,同步完了,再刪除 。-R:把目錄的結果一塊兒同步過去。
f_size=`du -sk $1|awk '{print $1}'` #判斷要刪除的文件的大小
disk_size=`LANG=en; df -k |grep -vi filesystem|awk '{print $4}' |sort -n |tail -n1` #
big_filesystem=`LANG=en; df -k |grep -vi filesystem |sort -n -k4 |tail -n1 |awk '{print $NF}'` #查看最大的分區答空間大小,並顯示出來。
if [ $f_size -lt $disk_size ] #要刪除的文件的大小小於磁盤空間,就能夠刪除了。
$big_filesystem/.$d && rsync -aR $1 $big_filesystem/.$d/$1 && /bin/rm -rf $1 #備份刪除的文件的,而後刪除。
for i in `seq 1 5`; do echo -ne ". "; sleep 1;done #停頓5秒,每停頓那一秒,就打印一個點。
若是發生誤刪的操做,立刻中止全部的寫的操做,那麼找回來的機會比較答。
來源 : https://github.com/aminglinux/shell100/blob/master/61.md