Linux shell get local ip address

Linux shell中获得本机IP的相关命令, 你知道几个?

hostname -I     # 不同系统返回不一样, 有些可能需要cut一下
ifconfig eth0 | grep inet | grep -v inet6 | awk '{print $2}'
ifconfig | awk '/inet addr/{print substr($2,6)}'
ifconfig | sed -n 's/.*inet addr:\([0-9.]\+\)\s.*/\1/p'
ip a s|sed -ne '/127.0.0.1/!{s/^[ \t]*inet[ \t]*\([0-9.]\+\)\/.*$/\1/p}'
ifconfig | perl -nle 's/dr:(\S+)/print $1/e'
curl ifconfig.me      # 适用于有公网IP的情况

Shell处理json数据

Shell处理json数据的方法,简单介绍一下,本文基于CentOS 6 64bit。

yum install jq    #需要EPEL源

下面我们有一个config.json文件

{
  "USERNAME": "admin",
  "CLUSTERMAP_HOSTS": {
      "staging":{
          "pc": "10.191.130.70",
          "app": "10.191.76.250",
          "wx": "172.28.172.171"
      },
      "production":{
          "mjq_pc":"172.28.139.30",
          "mjq_app":"172.28.148.150",
          "mjq_weixin":"172.28.149.84",
          "mjq_qq":"172.28.149.77",
          "lf_pc":"172.20.145.51",
          "lf_app":"172.20.145.40",
          "lf_weixin":"172.20.145.86",
          "lf_qq":"172.20.112.150",
          "jos":"172.20.145.50",
          "lf_coupon":"172.20.112.44",
          "mjq_coupon":"172.28.139.48"
      },
      "ab":{
          "mjq_pc":"172.28.175.36",
          "lf_app":"172.20.121.107"
      }
  },
  "CLUSTERMAP_BINARY_PATH": "/export/App/jd_search/clustermap/bin"
}

获得分片

$ cat config.json | jq '.CLUSTERMAP_HOSTS.production'
[
  {
    "lf_app": "172.20.121.107",
    "mjq_pc": "172.28.175.36"
  },
  {
    "mjq_coupon": "172.28.139.48",
    "lf_coupon": "172.20.112.44",
    "jos": "172.20.145.50",
    "mjq_pc": "172.28.139.30",
    "mjq_app": "172.28.148.150",
    "mjq_weixin": "172.28.149.84",
    "mjq_qq": "172.28.149.77",
    "lf_pc": "172.20.145.51",
    "lf_app": "172.20.145.40",
    "lf_weixin": "172.20.145.86",
    "lf_qq": "172.20.112.150"
  },
  {
    "wx": "172.28.172.171",
    "app": "10.191.76.250",
    "pc": "10.191.130.70"
  }
]

获得Key列表 继续阅读

Linux Shell之数组

一,数组定义

定义方法1
arr=(1 2 3 4 5) #用空格分开

定义方法2
array
array[0]="a"
array[1]="b"
array[2]="c"

定义方法3
str=“a b c”
array=($str)

二,数组调用及遍历

${#array[@]}      #获取数组的长度
echo ${array[@]}  #遍历数组(输出数组全部元素)
array[0]=5        #向数组的某个元素赋值
echo ${array[@]:1:2}  #输出array[0]和array[1]的值
echo ${array[@]:2}    #输出数组第三个元素以后的值
echo ${array[@]::2}   #输出数组下标小于2的值
$ echo ${#array[3]}   #取得元素3的长度
unset array    #清除array
array=         #清空array的值


遍历(For循环法)
for i in ${arr[@]}
do
    echo $i
done

遍历(For循环法2)
for ((i=0;i<${#array[@]};i++))
do
   echo ${array[$i]}
done

遍历(while循环法)
len=${#arr[@]}
i=0
while [ $i -lt $len ]
do
echo ${arr[$i]}
let i++
done

每隔30秒,查找名为ndh2nds的进程,找出其pid,修改/proc/$pid/oom_score_adj的值,防止该进程被OOM机制杀掉

#!/bin/bash

while :
do
  list=`ps -ef | grep -i ndh2nds | grep -v 'grep ' | awk '{print $2}'`
  array=($list)
  for pid in ${array[@]}
  do
    score=`cat /proc/$pid/oom_score_adj`
    echo oom_score_adj of pid $pid is $score
    if [ $score -ge 0 ]; then
      echo -100 > /proc/$pid/oom_score_adj
      echo changed oom_score_adj of pid $pid to `cat /proc/$pid/oom_score_adj`
    fi
  done
sleep 30
done

Linux Shell之括号用法

一,单小括号()
1,命令组。括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用。括号中多个命令之间用分号隔开,最后一个命令可以没有分号,各命令和括号之间不必有空格。
2,命令替换。等同于`cmd`,shell扫描一遍命令行,发现了$(cmd)结构,便将$(cmd)中的cmd执行一次,得到其标准输出,再将此输出放到原来命令。有些shell不支持,如tcsh。
3,用于初始化数组。如:array=(a b c d)

二,双小括号(( ))
1,整数扩展。这种扩展计算是整数型的计算,不支持浮点型。((exp))结构扩展并计算一个算术表达式的值,如果表达式的结果为0,那么返回的退出状态码为1,或者 是”假”,而一个非零值的表达式所返回的退出状态码将为0,或者是”true”。若是逻辑判断,表达式exp为真则为1,假则为0。
2,只要括号中的运算符、表达式符合C语言运算规则,都可用在$((exp))中,甚至是三目运算符。作不同进位(如二进制、八进制、十六进制)运算时,输出结果全都自动转化成了十进制。如:echo $((16#5f)) 结果为95 (16进位转十进制)
3,单纯用 (( )) 也可重定义变量值,比如 a=5; ((a++)) 可将 $a 重定义为6
4,双括号中的变量可以不使用$符号前缀。括号内支持多个表达式用逗号分开。

#判断大小
if ($i<5)  
if [ $i -lt 5 ]  
if [ $a -ne 1 -a $a != 2 ]  
if [ $a -ne 1] && [ $a != 2 ]  
if [[ $a != 1 && $a != 2 ]]  

#输出数0到4  
for i in $(seq 0 4);do echo $i;done  
for i in `seq 0 4`;do echo $i;done  
for ((i=0;i<5;i++));do echo $i;done  
for i in {0..4};do echo $i;done  

继续阅读

Linux Shell判断字符串是否存在包含关系

在Pyhton里判断字符串是否存在包含关系非常简单,只要if a in b就行了,但如何在Shell中判断字符串的包含关系呢?

#! /bin/bash

var1="hello"
var2="he"

#方法1
if [ ${var1:0:2} = $var2 ]; then
    echo "1:include"
fi

#方法2
echo "$var1" | grep -q "$var2"
if [ $? -eq 0 ]; then
    echo "2:include"
fi

#方法3
echo "$var1" |grep -q "$var2" && echo "include" ||echo "not"

#方法4
[[ "${var1/$var2/}" != "$var2" ]] && echo "include" || echo "not"

其他方法:
expr或awk的index函数
${var#...}                  
${var%...}
${var/.../...}

Shell之at命令(一定性定时计划任务)

at跟crontab一样,都是执行定时计划任务的命令。但不同的是,crontab执行的循环的任务,而at执行的是一次性任务,任务执行完以后便失效。

设置任务:

at now + 1 week -f a.sh      #a.sh必须已存在

at 01:35 < my-at-jobs.txt    
at < my.txt 01:35            #也可以把时间写在后面

at now +2 minutes <<< "mkdir 123"

at now +10 minutes <<ENDMARKER
rm -rf 123
echo successful done > /var/log/messages
ENDMARKER

查看所有任务:

at -l
atq

查看单个任务:

at -c ID

删除任务:

atrm 23
at -r 1

关于时间,可参考的语法: 继续阅读

shell中的日期时间处理

在Shell中的一些常见的处理时间的方法,这里记录一下。

$ date                        #获得当前日期
Sat Sep  6 23:31:48 CST 2014

$ date +%Y%m%d                #获得当前日期
20140906

$ date +%Y.%m.%d-%H:%M:%S     #获得当前日期
2014.09.06-23:32:56

$ date -d "-1 week" +%Y%m%d   #获取上周今日的日期
20140830

$ date -d "+3 day" +%Y%m%d    #获得3天后的日期
20140909

$ date -d "+1 month" +%Y%m%d  #获得1个月后的日期
20141006

$ date -d "+2 month 20131231" +%Y%m%d  #获得2013年12月31日以后2个月的日期
20140303

继续阅读