最新Linux运维必会22道Shellプログラミング面接问题すばらしい说明

12312 ワード

1.ランダム文字列を持つファイルを一括作成する方法
今回は$RANDOM変数に適用しました
作成コマンドは次のとおりです.
echo $RANDOM|md5sum|tr "[0-9]""[a-z]"|cut -c 3-8
ランダム数をechoで出力しmd 5で暗号化し、数字をアルファベットに変換して10個取ります
具体的なスクリプトは次のように実装されます.
#!/bin/bash
#echo $RANDOM|md5sum|tr "[0-9]" "[a-z]"|cut -c 3-8      
[ -d "/oldboy" ]|| mkdir -p /oldboy
for n in `seq 10`
do
   touch /oldboy/$(echo $RANDOM|md5sum|tr "[0-9]" "[a-z]"|cut -c 3-8)_oldboy.html
done

スクリプトの実行:
[root@Python test001]# sh oldboy01.sh

結果を表示:
[root@Python test001]# ls -rt /oldboy/
gdcffb_oldboy.html  fghgca_oldboy.html  jffffh_oldboy.html  dhbdec_oldboy.html  fgjehc_oldboy.html
ecfbca_oldboy.html  gigcfe_oldboy.html  deabbf_oldboy.html  jbfbia_oldboy.html  chacif_oldboy.html
[root@Python test001]#

注記:ランダム文字を取得するには:
[root@Python test001]# openssl rand -base64 40|sed 's#[^a-z]##g'
acgilbtgjwpkejryjybkg

以上のスクリプトは、次のように書き換えることができます.
#!/bin/bash
Path=/oldboy
[ -d "$Path" ]|| mkdir -p /oldboy
for n in `seq 10`
do
   random=$( openssl  rand -base64 40|sed 's#[^a-z]##g'|cut -c 2-11)
   touch /oldboy/${random}_oldboy.html
done

スクリプトの実行:
[root@Python test001]# ll -rth /oldboy/
total 0
-rw-r--r-- 1 root root 0 Jan 22 09:58 uxodkflbvk_oldboy.html
-rw-r--r-- 1 root root 0 Jan 22 09:58 hegdftlpsg_oldboy.html
-rw-r--r-- 1 root root 0 Jan 22 09:58 dztkcvtris_oldboy.html
-rw-r--r-- 1 root root 0 Jan 22 09:58 uthjkiobcr_oldboy.html
-rw-r--r-- 1 root root 0 Jan 22 09:58 efzdhgafvp_oldboy.html
-rw-r--r-- 1 root root 0 Jan 22 09:58 ygxdfyqcyq_oldboy.html
-rw-r--r-- 1 root root 0 Jan 22 09:58 pxqaxozaim_oldboy.html
-rw-r--r-- 1 root root 0 Jan 22 09:58 ybbnmsuinc_oldboy.html
-rw-r--r-- 1 root root 0 Jan 22 09:58 ebvpjhaith_oldboy.html
-rw-r--r-- 1 root root 0 Jan 22 09:58 lzxgyzqrbd_oldboy.html

2、大量にファイル名を修正する方法の説明
今回はコマンドのつなぎ合わせに関し,forループを用いてファイルを取り出し,awkを介して「」分割を行い、固定接尾辞(print$1)を取り出し、mvコマンドを実行してソースファイル$nを$name${Filename}に名前を変更します.
#!/bin/bash
Filename=_.oldgirl.HTML
Dirname="/oldboy"
cd $Dirname
for n in `ls /oldboy`
do
  name=$(ls /oldboy/${n}|awk -F:'_' '{print $1}')
  mv $n ${name}${Filename}
done

[root@Python test001]# 
または
#!/bin/bash
Filename=_oldgirl.HTML
Dirname="/oldboy"
cd $Dirname
for n in `ls`
do
    name=$(echo ${n}|awk -F '_' '{print $1}')
    mv $n ${name}{Filename}
done

以上のスクリプトをawkで書き換えるか
#!/bin/bash
Path="/oldboy"
cd $Path && \
ls $Path|xargs -n1|awk -F '_' '{print "mv "$0" "$1"_oldgirl.HTML"}'|bash

注記:xargs-nlは不要です.また、上記のスクリプトのmvはrenameで置き換えることができます.すなわち、次のようになります.
#!/bin/bash
Path="/oldboy"
cd $Path && \
ls $Path|xargs -n1|awk -F '_' '{print "rename "$0" "$1"_oldgirl.HTML"}'|bash

3、大量に10個のシステムアカウントを作成し、パスワードを設定する多種の方法
運用する知識点:
①useradd oldboy01
②echo "pass"|passwd --stdin oldboy
③アカウントを作成する前に0を追加するには、次の2つの方法があります.
1、seq -w 10
2、echo {00..10}
[root@Python test001]# seq -w 10
01
02
03
04
05
06
07
08
09
10
[root@Python test001]# echo {00..10}
00 01 02 03 04 05 06 07 08 09 10
[root@Python test001]#

④    ,   6   
⑴ $RANDOM
[root@Python test001]# echo $RANDOM|md5sum |cut -c 2-9
e691e92d
 
⑵ openssl #  openssl     
[root@Python test001]# openssl rand -base64 45
i9IzYMu6QCIxSPLt0BQdkFzhA3ydJ12Y4mjcCL4zFMjVqBPjEGDmCQ+n5lPF
[root@Python test001]#

(3)dateコマンド
[root@Pythontest 001]#date+%s/%N#時間取得乱数
1453431452/536836731
[root@Python test001]# date +%s/%N|md5sum|tr "[0-9]""[0-9][a-zA-Z]"
54af7dcb18a35cda83f299c7f389b720  -
(4)head/dev/urandom|cksum#デバイスによる乱数発生
[root@Python test001]# head/dev/urandom|cksum
2049066555 2401
[root@Python test001]# 
(5)uuid通過乱数
[root@Python test001]# cat/proc/sys/kernel/random/uuid 
1ea4deab-debc-4800-89d3-1817c198315b
[root@Python test001]# 
(6)exectによる乱数
[root@Python test001]# yum -y install expect
[root@Python test001]# mkpasswd -l 10 -d 5 
kn5G51X;73
[root@Python test001]# 
実装コードは次のとおりです.
#!/bin/bash
[ -f /etc/init.d/functions ]&& source /etc/init.d/functions
[ $UID -ne 0 ]&&{echo "pls sudo to root "}
for  user in oldgirl{00..10}
do 
  work=$(grep "\b$user\b" /etc/passwd|wc -l)
  if [ $work -eq 1 ];then
       action "Useradd $user already exists" /bin/false
       continue
  fi
  pass=$(echo $RANDOM|md5sum|cut -c 1-8)
  useradd $user && echo "pass"|passwd --stdin $user &>/dev/null
  RETVAL=$?
  if [ $RETVAL -eq 0 ];then
        action "Useradd $user is OK" /bin/true
  fi
  echo -e "\033[32m"$user"\033[0m \t \033[31m "$pass"\033[0m">>/tmp/user.txt
done

注記:上記のスクリプトは知識点に設計されています.
a、引用システム関数ライブラリ
b、作成するユーザが存在するか否かを判断する「grepb$userb」を用いて正確にマッチングし、grep「b$userb」/etc/passwd|wc-lを1つの変数に付与し、ユーザが存在するか否かを判断することを判断変数値が1であるか否かに変換する
c、ユーザーの作成と生産のランダムパスワードを処理する時、&&記号を運用して、口座を成功させた後にパスワードを付与する
d、実行スクリプトのユーザーIDがrootであるかどうかを判断し、そうでなければプロンプト文を印刷する
もう1つの方式の実装(コマンドライン)
運用知識点:
a、xargs -nn
前の内容をパイプを介してxargs-n処理に渡し,列に分割し,後のnは1,2,3,4,5の値をとる
[root@Python test001]# echo old{01..10}|xargs -n1
old01
old02
old03
old04
old05
old06
old07
old08
old09
old10
[root@Python test001]# echo old{01..10}|xargs -n2
old01 old02
old03 old04
old05 old06
old07 old08
old09 old10
[root@Python test001]# echo old{01..10}|xargs -n3
old01 old02 old03
old04 old05 old06
old07 old08 old09
old10
[root@Python test001]# echo old{01..10}|xargs -n4
old01 old02 old03 old04
old05 old06 old07 old08
old09 old10
b、sed文法による置換
実装コード:
次のようにデバッグします.
[root@Python test001]# echo old{01..10}|xargs -n1|sed -r 's#(.*)#useradd\1;pass=$(echo $RANDOM|md5sum|cut -c 1-8);echo "$pass"|passwd --stdin\1;echo -e "\1"\t "$pass">>/tmp/use.txt#g'  
useradd old01;pass=$(echo $RANDOM|md5sum|cut -c 1-8);echo "$pass"|passwd --stdin old01;echo -e "old01"  "$pass">>/tmp/use.txt
useradd old02;pass=$(echo $RANDOM|md5sum|cut -c 1-8);echo "$pass"|passwd --stdin old02;echo -e "old02"  "$pass">>/tmp/use.txt
useradd old03;pass=$(echo $RANDOM|md5sum|cut -c 1-8);echo "$pass"|passwd --stdin old03;echo -e "old03"  "$pass">>/tmp/use.txt
useradd old04;pass=$(echo $RANDOM|md5sum|cut -c 1-8);echo "$pass"|passwd --stdin old04;echo -e "old04"  "$pass">>/tmp/use.txt
useradd old05;pass=$(echo $RANDOM|md5sum|cut -c 1-8);echo "$pass"|passwd --stdin old05;echo -e "old05"  "$pass">>/tmp/use.txt
useradd old06;pass=$(echo $RANDOM|md5sum|cut -c 1-8);echo "$pass"|passwd --stdin old06;echo -e "old06"  "$pass">>/tmp/use.txt
useradd old07;pass=$(echo $RANDOM|md5sum|cut -c 1-8);echo "$pass"|passwd --stdin old07;echo -e "old07"  "$pass">>/tmp/use.txt
useradd old08;pass=$(echo $RANDOM|md5sum|cut -c 1-8);echo "$pass"|passwd --stdin old08;echo -e "old08"  "$pass">>/tmp/use.txt
useradd old09;pass=$(echo $RANDOM|md5sum|cut -c 1-8);echo "$pass"|passwd --stdin old09;echo -e "old09"  "$pass">>/tmp/use.txt
useradd old10;pass=$(echo $RANDOM|md5sum|cut -c 1-8);echo "$pass"|passwd --stdin old10;echo -e "old10"  "$pass">>/tmp/use.txt
デバッグ結果のbash実行への渡し
[root@Python test001]# echo old{01..10}|xargs -n1|sed -r 's#(.*)#useradd\1;pass=$(echo $RANDOM|md5sum|cut -c 1-8);echo "$pass"|passwd --stdin\1;echo -e "\1"\t "$pass">>/tmp/use.txt#g'|bash
初期コードを拡張する(ckpasswdコマンドを使用):
#!/bin/bash
[ -f/etc/init.d/functions ]&& source/etc/init.d/functions
[ $UID -ne 0 ]&&{echo "pls sudo to root "}
for  user in admin{00..10}
do 
  work=$(grep "\b$user\b"/etc/passwd|wc -l)
  if [ $work -eq 1 ];then
       action "Useradd $user already exists"/bin/false
       continue
  fi
  pass=$(echo $RANDOM|md5sum|cut -c 1-8)
  useradd $user && echo "$user:$pass"|tee >>/tmp/userlist.log|chpasswd
done
[root@Python test001]# 
スクリプトの実行:
[root@Python test001]# sh oldboy04-02.sh    
[root@Python test001]# cat/tmp/userlist.log 
admin00:9ed66b14
admin01:29af36b7
admin02:48929baa
admin03:8d541efd
admin04:0f8ea01f
admin05:994f8644
admin06:109e40a2
admin07:5c5a654b
admin08:9959dbbf
admin09:6847874d
admin10:4412f63c
[root@Python test001]#
3、開発シナリオDOS攻撃の生産ケースを解決する多種の方法説明
シナリオを書いてDOS攻撃の生産ケースを解決します
ヒント:ヒントWebログまたはネットワーク接続数に基づいて、あるIP同時接続数または短期間のPVが100に達した場合、すなわちファイアウォールコマンドを呼び出して対応するIPを閉鎖し、監視頻度は3分おきである.
Webログ分析によると、日付ファイルはaccess_2016-01-22.log
#!/bin/bash
[ -f /etc/init.d/functions ] && source /etc/init.d/functions
Path=/root/system/test001/access_2016-01-22.log
count=10
function ipt(){
awk '{print $1}' $Path|sort|uniq -c|sort -nr -k1 >/tmp/tmp.log
exec </tmp/tmp.log
while read line
do
 IP=`echo $line|awk '{print $2}'`
 if [ `echo $line|awk '{print $1}'` -ge $count -a `iptables -L -n|grep "$IP"|wc -l` -lt 1 ];then
       iptables -I INPUT -s $IP -j DROP
       RETVAL=$?
       if [ $RETVAL -eq 0 ];then
           action "$IP is  DROP" /bin/true
           echo "$IP" >>/tmp/ip_$(date +%F).log
       else
            action "$IP is DROP" /bin/false
       fi
 fi
done
}
function del(){
[ -f /tmp/ip_$(date+%F -d '-1day').log ]||{echo "ip_$(date+%F -d '-1day').log is not exist";exit 1}
exec >/tmp/ip_$(date+%F -d '-1day').log
while read line
do
if [ `iptables -L -n|grep "$line"|wc -l` -ge 1 ];then
       iptables -D INPUT -s $line -j DROP 
fi
done
}
main(){
   flag=0
   while true
   do 
       sleep 3
       ((flag++))
       ipt
       [ $flag -ge 3 ] && del && flag=0
   done
}
main

4、英語のアルファベット数が6以下の単語を出力する(昆仑万維面接問題)
I am oldboy teacher welcome to oldboy training class
考え方:
まず、各単語を取り出して各単語の文字数を表示する必要があります.単語を取るには、次の2つの方法があります.
⑴配列
(2)文字列(wc-w脱文字の単語数)
単語の長さを取る方法:
①${#変数}
②wc -L
③wc-c(改行文字が多いので文字列長より1多い)
④${変数:0:6}元の変数と比較
⑤expr length「変数」
⑥awk'{print length($変数)}'
実装コード①
#!/bin/bash
array=(I am oldboy teacher welcome to oldboy training class)
funFirst(){
     for word in  ${array[*]}
     do
        if [ ${#word} -le 6 ];then
            echo $word
        fi
     done
}
funFirst

実装コード②
#!/bin/bash
array=(I am oldboy teacher welcome to oldboy training class)
funFirst(){
     for word in  ${array[*]}
     do
        if [ $(echo $word|wc -L) -le 6 ];then
            echo $word
        fi
     done
}
funFirst

実装コード③
#!/bin/bash
array=(I am oldboy teacher welcome to oldboy training class)
funFirst(){
     for word in  ${array[*]}
     do
         check=$(echo $word|awk '{print length ($word)}')
        if [ $check -le 6 ];then
            echo $word
        fi
     done
}
funFirst

実装コード④
[root@Python test001]# word="I am oldboy teacher"                    
[root@Python test001]# echo $word|xargs -n1|awk 'length >4{print $1}'
oldboy
teacher

実装コード⑤
[root@Python test001]# echo "I am oldboy teacher welcome to oldboy training"|tr " " "
"|awk '{if (length($1)<=6) print $1}'  I am oldboy to oldboy [root@Python test001]#

5、二つの整数サイズを比較し、厳密にパラメータ入力を判断する