欢迎访问www.showerlee.com, 您的支持就是我前进的动力.

[SHELL]shell scripts笔记(2)

showerlee 2013-08-27 18:58 SHELL 阅读 (6,044) 抢沙发

最近一直在研究shell脚本,整理了些比较有用的以备不时之需。。

1.获取字符串长度

# var=1234567890

# echo ${#var}

2.识别当前shell版本

# echo $SHELL

# echo $0

3.检查是否为超级用户

-------------------------

#!/bin/bash

if [ $UID -ne 0 ];then

echo Non root user .Please run as root.

else

echo "Root user"

fi

-------------------------

4.修改Bash提示字符串

# cat /etc/bashrc | grep PS1

5.重定向脚本内部的文本块

-------------------------

#!/bin/bash

cat <<EOF>>log.txt

LOG FILE HEADER

This is a test log file

Function: System statistions

EOF

-------------------------

6.删除空白行

# cat file.txt | tr -s '\n'

# cat file.txt | sed '/^$/d'

7.find忽略大小写

# find . -iname "example" -print

8.find 匹配多个条件

# find . \( -name "*.txt" -o -name "*.pdf" \) -print

9.否定参数

# find . ! -name "*.txt" -print

10.结合find使用xargs

# find . -type f -name "*.txt" -print0 | xargs -0 rm -f

注:这里xargs -0将\0作为输入定界符,防止搜索到带空格的字符后被find识别成2个文件

11.生成一个大小为100K的测试文件

# dd if=/dev/zero bs=100k count=1 of=date.file

12.用特定格式重命名当前目录下的图像文件、

-------------------------------

#!/bin/bash

count=1

for img in *.jpg *.png

do

  new=image-$count.${img##*.}

  mv "$img" "$new" 2> /dev/null

if [ $? -eq 0 ];

  then

  echo "Renaming $img to $new"

  let count++

fi

done

-------------------------------

13.URL="www.google.com"

# echo ${URL%.*} # 移除 .*所匹配的最右边的内容

http://www.google

# echo ${URL%%.*} # 将从右边开始一直匹配到最左边的*.移除(贪婪操作符)

www

# echo ${URL#*.} # 移除*.所匹配的最左边的内容

google.com

# echo ${URL##*.} # 将从左边开始一直匹配到最右边的*.移除(贪婪操作符)

com

14.将一个文件设置为不可修改:

# chattr +i file

恢复:

# chattr -i file

15.生成不同的空白文件:

----------------

for name in (1...100).txt

do

touch $name

done

----------------

16.移除空白行

# sed '/^$/d' file

17.打印可用的网络接口

# ifconfig | cut -c-10 |tr -d ' ' |tr -s '\n'

注:cut -c-10为提取每行前10个字符,也可以这么写 cut -c1-10,tr -d ' '为删除每行所有空格,tr -s  '\n'为用单独的换行替换每一序列的一个或多个换行。

# ifconfig | grep '^[a-z].*' |cut -c-5

18.提取IP地址:

# ifconfig eth0 | grep 'inet addr:[0-9].*'|awk -F' ' '{print $2}'|awk -F':' '{print $2}'

子网掩码:

# ifconfig eth0 |grep  '.*Mask:[0-9].*$' |awk -F':' '{print $4}'

网关:

# route |grep "^default" |awk -F' ' '{print $2}'

MAC:

# ifconfig eth0 |grep '^.*HWaddr.*$'| awk -F' ' '{print $5}'

19.添加DNS

# echo "nameserver 61.134.1.4" >> /etc/resolv.conf

20.添加临时网关

# route add default gw 192.168.7.1 eth0

21.查看网内主机活动状态:

-------------------

#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin

export PATH

NET_NUM=$(ifconfig eth0 | grep 'inet addr:[0-9].*'|awk -F' ' '{print $2}'|awk -F':' '{print $2}'|awk -F'.' '{print $1"."$2"."$3}')

for IP in $NET_NUM.{1..254};

do

  ping $IP -c2 &> /dev/null ;

  if [ $? -eq 0 ];

  then

     echo $IP is alive

  fi

done

-------------------

22.配置IP地址

-----------------------

#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin/:/usr/local/bin:/usr/local/sbin:~/bin

export PATH

IFACE=eth0

IP_ADDR=192.168.7.74

NET_MASK=255.255.255.0

GW=192.168.7.1

# 判断是否为root权限

if [ $UID -ne 0 ];

then

  echo "Run as root"

  exit 1

# 关闭eth0

ifconfig $IFACE down

#配置IP和掩码

ifconfig $IFACE $IP_ADDR netmask $NET_MASK

#配置网关

route add default gw $GW $IFACE

# 开启eth0

ifconfig $IFACE up

echo "Successfully configured $IFACE"

-----------------------------

23.收集远程主机运行时间(先做加密认证)

-----------------------

#!/bin/bash

IP_LIST="192.168.0.[1..254]"

USER="test"

for IP in $IP_LIST;

do

  UPTIME=$(ssh $USER@$IP uptime |awk '{print $3}')

  echo "$IP uptime: $UPTIME"

done

------------------------

24.列出本地当前开放的端口

# netstat -ntulp |grep LISTEN |awk -F' ' '{print $4}'|sed 's/^0.0.0.0://g'|sed 's/^127.0.0.1://g'|sed 's/^::://g'|sed 's/^::1://g'|sort -n|uniq -c|awk -F' ' '{print $2}'

# yum install nmap -y && nmap -p1-65535 localhost

25.找出指定目录中最大的十个文件

# du -ak . |sort -nrk 1 | head -n 10

注:-a指定了所有目录和文件,-k输出第一列以KB为单位的文件大小,sort对第一列依数值逆序排序,head用来显示前10行输出

# find . -type f -exec du -k {} \; |sort -nrk 1 |head -n 10

或(推荐,效率最高)

# find . -type f -print0 |xargs -0 du -k |sort -nrk 1 |head -n 10

26.计算命令执行时间

# time find . -type f -exec du -k {} \; |sort -nrk 1 |head -n 10

# time find . -type f -print0 |xargs -0 du -k |sort -nrk 1 |head -n 10

27.打印出10条最常用的命令

------------------------------

#!/bin/bash

printf "COMMAND\tCOUNT\n";

cat ~/.bash_history | awk '{ list[$1]++; } \

END{

for(i in list)

{

printf("%s\t%d\n",i,list[i]); }

}'| sort -nrk 2 | head

------------------------------

注:

   在上面的脚本中,用~/.bash_history作为源文件,通过管道将源输入传递给awk,在awk中,我们使用了一个关联数组,这个数组将命令作为索引,将命令的出现的次数作为数组元素值。命令每出现一次,计数值增加1(list[$1]++).$1是输入文本行的第一个单词,如果使用$0,则包含输入文本行中所有的单词。

   比如说,如果ssh 192.168.0.4是.bash_history其中的一行,那么$0中包含ssh 192.168.0.4,$1中包含ssh.

   一旦对命令历史文件中的所有行遍历完毕,我们就得到了一个数组,其中数组索引是命令名称,数组元素值是命令出现的次数,因此出现次数最多的命令名称就是使用最频繁的命令。

   在awk的END{}语句块中,我们遍历关联数组,打印出所有的命令名及其对应的出现次数,sort -nrk 2 对第2列(COUNT)按照数值逆序排序,最后用head 命令从列表中提取出前10条命令,你可以用head -n NUMBER将前10条命令改为前5条或者是其他任意数量。

30.列出1小时内占用CPU最多的10个进程:

-----------------------

#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin

export PATH

SECS=3600

UNIT_TIME=60

#secs为需要进行监视的总秒数

#UNIT_TIME是取样的时间间隔,单位是秒

STEPS=$(( $SECS / $ UNIT_TIME ))

echo Watching CPU usage... ;

for((i=0;i<STEPS;i++))

do

 ps -eo comm,pcpu | tail -n +2 >> /tmp/cpu_usage.$$

 sleep $UNIT_TIME

done

echo

echo CPU eaters;

cat /tmp/cpu_usage.$$ | \

awk '

{ process[$1]+=$2; }

END{

  for(i in process)

  {

     printf("%-20s %s",i, process[i]) ;

   }

   }' | sort -nrk 2 | head

rm /tmp/cpu_usage.$$

#删除临时日志文件

-----------------------

注:在上面的脚本中,主要的输入源是ps -eo comm,pcpu,其中comm表示命令名(command name),pcpu表示CPU使用率(CPU usage in percent)。该命令输出所有进程名及CPU使用率,每个进程对应一行输出。因为需要监视一个小时内CPU的使用情况,所以我们得在一个每次迭代时间为60秒的for循环中不停的用ps -eo comm,pcpu |tail -n +2来获取CPU的使用统计数据,并将这些数据添加到文件/tmp/cpu_usage.$$中,60秒的迭代时间通过sleep 60来提供,这就使得每一分钟执行一次ps

   tail -n +2用来将ps 输出中的头部和COMMAND %CPU剥离.

   cpu_usage.$$中的$$表示当前脚本的进程ID,假设进程ID为1345,那么在脚本执行时,他会被替换成/tmp/cpu_usage.1345,因为这是一个临时文件,所以我们把它放在/tmp中。

   统计文件在1小时后就准备妥当了,文件中包含了60项,分别对应每分钟的进程状态,然后用awk求出每个进程中的CPU使用情况,我们用了一个关联数组来统计CPU的使用情况,其中进程名为数组索引,最后根据总的CPU使用情况依数值逆序排序,并通过head获得前10项。

31.利用watch监控命令查看输出

# watch -n 5 ls

注:利用此命令可以查看该目录的文件变化, -n 5 为间隔5秒更新一次

32.扫描secure日志文件并收集所需信息,生成入侵检测报告

方法一.扫描他人利用系统认证用户进行暴力破解。

---------------------------

#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin

export PATH

AUTHLOG=/var/log/secure

if [ [ -n $1] ];

then

  AUTHLOG=$1

  echo Using Default Log file : $AUTHLOG

fi

LOG=/tmp/valid.$$.log

grep  -v "invalid" $AUTHLOG > $LOG

users=$(grep "Failed password" $LOG | awk '{ print $(NF-5) }'| sort | uniq)

printf "%-5s|%-10s|%-10s|%-13s|%-13s|%-33s|%s\n" "No#" "User" "Attepts" "IP address" "Host_Mapping" "Time range"

ucount=0

ip_list="$(egrep -o "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" $LOG | sort | uniq)"

for ip in $ip_list;

do

  grep $ip $LOG > /tmp/temp.$$.log

for user in $users;

do

  grep $user /tmp/temp.$$.log > /tmp/$$.log

  cut -c-16 /tmp/$$.log > $$.time

  #显示登录时间

  tstart=$(head -1 $$.time);

  #显示从1970年到该时刻所经历的秒数

  start=$(date -d "$tstart" "+%s");

  #显示登出时间

  tend=$(tail -1 $$.time);

  #显示从1970年到该时刻所经历的秒数

  end=$(date -d "$tend" "+%s")

  #算出登录时间

  limit=$(( $end - $start ))

  if [ $limit -gt 1 ];

then

  let ucount++;

  IP=$(egrep -o "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" /tmp/$$.log | head -1 );

  TIME_RANGE="$tstart --> $tend"

  ATTEMPTS=$(cat /tmp/$$.log | wc -l)

  HOST=$(host $IP | awk '{print $NF}')

  printf "%-5s|%-10s|%-10s|%-13s|%-13s|%-33s|%s\n" "$ucount" "$user" "$ATTEMPTS" "$IP" "$HOST" "$TIME_RANGE";

  fi

done

done

rm /tmp/valid.$$.log /tmp/$$.log $$.time /tmp/temp.$$.log 2> /dev/null

---------------------------

方法二.扫描他人利用系统认证用户或非系统用户进行暴力破解。

---------------------------

#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin

export PATH

AUTHLOG=/var/log/secure

if [[ -n $1 ]];

then

  AUTHLOG=$1

  echo Using Log file : $AUTHLOG

else

  echo Using Default Log file : $AUTHLOG

fi

LOG=/tmp/valid.$$.log

grep "Failed password" $AUTHLOG > $LOG

users=$(cat $LOG | awk '{ print $(NF-5) }'| sort | uniq)

printf "%-5s|%-10s|%-10s|%-13s|%-13s|%-33s|%s\n" "No#" "User" "Attepts" "IP address" "Host_Mapping" "Time range"

ucount=0

ip_list="$(egrep -o "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" $LOG | sort | uniq)"

for ip in $ip_list;

do

  grep $ip $LOG > /tmp/temp.$$.log

for user in $users;

do

  grep $user /tmp/temp.$$.log > /tmp/$$.log

  cut -c-16 /tmp/$$.log > $$.time

  #显示登录时间

  tstart=$(head -1 $$.time);

  #显示从1970年到该时刻所经历的秒数

  start=$(date -d "$tstart" "+%s");

  #显示登出时间

  tend=$(tail -1 $$.time);

  #显示从1970年到该时刻所经历的秒数

  end=$(date -d "$tend" "+%s")

  #算出登录时间

  limit=$(( $end - $start ))

  if [ $limit -ge 0 ];

then

  let ucount++;

  IP=$(egrep -o "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" /tmp/$$.log | head -1 );

  TIME_RANGE="$tstart --> $tend"

  ATTEMPTS=$(cat /tmp/$$.log | wc -l)

  HOST=$(host $IP | awk '{print $NF}')

  printf "%-5s|%-10s|%-10s|%-13s|%-13s|%-33s|%s\n" "$ucount" "$user" "$ATTEMPTS" "$IP" "$HOST" "$TIME_RANGE";

  fi

done

done

rm /tmp/valid.$$.log /tmp/$$.log $$.time /tmp/temp.$$.log 2> /dev/null

---------------------------

33.监视远程磁盘的健康情况

----------------------------

#!/bin/bash

logfile="diskusage.log"

if [[ -n $1 ]]

then

  logfile=$1

fi

if [ ! -e $logfile ]

then

  printf "%-8s %-14s %-9s %-8s %-6s %-6s %-6s %s\n" "Data" "IP address" "Device" "Capacity" "Used" "Free" "Percent" "Status" > $logfile

fi

IP_LIST="192.168.7.74"

{

for ip in $IP_LIST;

do

  ssh $ip 'df -h' |grep ^/dev/ > /tmp/$$.df

  while read line;

  do

    cur_date=$(date +%D)

    printf "%-8s %-14s " $cur_date $ip

    echo $line | awk '{ printf("%-9s %-8s %-6s %-6s %-8s",$1,$2,$3,$4,$5);}'

    pusg=$(echo $line | egrep -o "[0-9]+%")

    # 参见man bash 找${parameter/pattern/string}

    # .${parameter/pattern/string} ${parameter//pattern/string}

    # 在这里pattern也是一个模式,parameter展开后最长匹配的部分被string替换。      # 第一种情况只替换首次匹配,第二种情况替换所有匹配。

    pusg=${pusg/\%/};

    if [ $pusg -lt 80 ];

    then

       echo SAFE

    else

       echo ALERT

    fi

    done < /tmp/$$.df

   done

   } >> $logfile

----------------------------

34.创建数据库及数据表脚本

-------------------------------

#!/bin/bash

USER="root"

PASS="123456"

DB="test1"

TABLE="test1"

mysql -u $USER -p$PASS <<EOF 2> /dev/null

CREATE DATABASE $DB;

EOF

[ $? -eq 0 ] && echo Created $DB || echo $DB already exist

mysql -u $USER -p$PASS $DB <<EOF 2> /dev/null

CREATE TABLE $TABLE(

id int,

name varchar(100),

mark int,

dept varchar(4)

);

EOF

[ $? -eq 0 ] && echo Created table $TABLE || echo Table $TABLE already exist

-------------------------------

或(传参)

------------------------------

#!/bin/bash

USER="root"

PASS="123456"

DB="$1"

TABLE="$2"

if [ $# -ne 2 ]; # if传参的个数不等于2

then

  echo "please input the db and table name.exp: {sh db table}" && exit 0

elif [ "$1" -gt 0 -o "$2" -gt 0 ] 2>/dev/null ;

then

  echo "please input the right name(not number).exp: {sh db table}" && exit 0

fi

mysql -u $USER -p$PASS <<EOF 2> /dev/null

CREATE DATABASE $DB;

EOF

[ $? -eq 0 ] && echo Created $DB || echo $DB already exist

mysql -u $USER -p$PASS $DB <<EOF 2> /dev/null

CREATE TABLE $TABLE(

id int,

name varchar(100),

mark int,

dept varchar(4)

);

EOF

[ $? -eq 0 ] && echo Created table $TABLE || echo Table $TABLE already exist

------------------------------

35.将数据插入数据表:

-------------------------------

#!/bin/bash

USER="root"

PASS="123456"

if [ $# -ne 1 ];

then

  echo $0 DATAFILE

  echo

  exit 2

fi

data=$1

while read line;

do

 oldIFS=$IFS

 IFS=.

 values=($line)

 values[1]="\"`echo ${values[1]} | tr ' ' '#' `\""

 values[3]="\"`echo ${values[3]}`\""

 query=`echo $(values[@]) | tr ' #' ', ' `

 IFS=$oldIFS

 mysql -u $USER -p$PASS students <<EOF

INSERT INTO students VALUES($query);

EOF

done < $data

echo Wrote data into DB

-------------------------------

正文部分到此结束
版权声明:除非注明,本文由(showerlee)原创,转载请保留文章出处!
本文链接:http://www.showerlee.com/archives/599

继续浏览:SHELL

还没有评论,快来抢沙发!

发表评论

icon_wink.gif icon_neutral.gif icon_mad.gif icon_twisted.gif icon_smile.gif icon_eek.gif icon_sad.gif icon_rolleyes.gif icon_razz.gif icon_redface.gif icon_surprised.gif icon_mrgreen.gif icon_lol.gif icon_idea.gif icon_biggrin.gif icon_evil.gif icon_cry.gif icon_cool.gif icon_arrow.gif icon_confused.gif icon_question.gif icon_exclaim.gif