博客园  :: 首页  :: 新随笔  :: 订阅 订阅  :: 管理

python -c 执行单行命令或脚本

Posted on 2022-10-24 21:48  面具下的戏命师  阅读(506)  评论(0编辑  收藏  举报

python -c 执行单行命令或脚本

背景:

最近在编写 shell 脚本实现数据库的自动巡检功能,在某些巡检项需要处理 json 类型的数据。使用不擅长处理字符串的 shell来处理 json, 各种awk  sed grep 搞下来差点脑溢血。最后还是解析不了复杂的 json。一通查资料,搞到如下三种方案:

1、安装 jq 工具,使用 jq 来解析。弊端,生产环境可能没有 jq

2、使用 awk sed,利用正则匹配进行切割

3、借助第三方解析器,如python php 等

方案一:

比较好用,需要安装 jq。jq 的使用自行百度

方案二:

优点是无需额外的依赖,缺点是有些 JSON 格式无法正常获取,需要根据实际情况修改相关的正则或命令参数。各种复杂的正则匹配。

function get_json_value()
{
  local json=$1
  local key=$2
 
  if [[ -z "$3" ]]; then
    local num=1
  else
    local num=$3
  fi
 
  local value=$(echo "${json}" | awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/'${key}'\042/){print $(i+1)}}}' | tr -d '"' | sed -n ${num}p)
 
  echo ${value}

方案三:

虽然 bash/sh 没有专门处理 JSON 的功能,但是其他脚本解释器通常都是有的,比如 Python、php。本文介绍一下 python, 强大的 python 从未让人失望。

shell 调用python解析json 数据

刚开始笔者的想法是单独写一个python 脚本来解析 json 数据,然后在 shell 中再调用这个python 脚本。这样有个弊端是,一个巡检脚本要拆分成两个,shell 接收 python 返回的解析后的数据再次进行处理。在经过一番搜索之后,发现python提供了 -c 参数,可以在 bash 终端直接执行指令。

例如:

python -c "import os;print('hello'),print('world')"
python -c "import os;print('hello');print('world')"

要用双引号将命令包起来,import要以**;结尾,命令用[]括起来,多行命令用多个[]**

python -c "import os,time;[print(i) for i in os.listdir()];[print(time.time())]"
python -c "import os,time;[print(i) for i in os.listdir()],[print(time.time())]"

复杂的命令必须要用**[]**括起来,否则会报错。格式上还可以多尝试一下:

python -c "print('hello');print('world')"
python -c "print('hello'),print('world')"
python -c "[print('hello'),print('world')]"
python -c "[print('hello')],[print('world')]"

以上命令在 python3 的版本可以正常执行

但是当发现了新大陆,兴高采烈的去使用的时候。发现服务器上安装的是 python2 版本。部分格式根本执行不通,wtf!!!

再次经过一番资料查询,在 python2 中同样找到了替代方案:

python -c "exec(\"n = 3\nfor i in range(n):\n  print(i)\")"

或者可以插入真正的新行:

$ python2 -c "n = 3
> for i in range(n):
>   print(i)"
0
1
2

附:最终采用的格式:

echo ${topo} | python -c "exec(\"import sys, json\nfor i in json.load(sys.stdin)['${tsc}']['slave']:\n    print(i)\")"`)

bingo!