帮忙看看这个 shell 脚本,搞不定。。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
mikaelson
V2EX    Linux

帮忙看看这个 shell 脚本,搞不定。。

  •  
  •   mikaelson 2021-05-19 10:46:59 +08:00 4380 次点击
    这是一个创建于 1688 天前的主题,其中的信息可能已经有所发展或是发生改变。

    #!/bin/bash OLD_INFO=hostlist

    for IP in $(awk '/^[^#]/{print $1}' $OLD_INFO); do

    USER=$(awk -v I=$IP 'I==$1{print $2}' $OLD_INFO) PASS=$(awk -v I=$IP 'I==$1{print $3}' $OLD_INFO) PORT=$(awk -v I=$IP 'I==$1{print $4}' $OLD_INFO) NEW_PASS=$(awk -v I=$IP 'I==$1{print $5}' $OLD_INFO) expect -c" spawn ssh -p$PORT root@$IP set timeout 15 expect { \"(yes/no)\" {send \"yes\r\";exp_continue} \"password:\" {send \"$PASS\r\";exp_continue} \"# \" {send \"echo \'$NEW_PASS\'|passwd --stdin $USER\r exit\r\";exp_continue} }" 

    done

    当 hostlist 文件里的多行记录出现同一个 IP 时。。。脚本就不行了,比如内容如下

    192.168.128.130 test 123456 22 abc*123

    192.168.128.131 a 123456 22 abc*123

    我把脚本改成 for line in hostlist,按行读取,再加个 IP 参数,又是另一种错误了。。。

    22 条回复    2021-05-25 22:06:56 +08:00
    jmyz0455
        1
    jmyz0455  
       2021-05-19 10:58:16 +08:00
    “不行”是指脚本异常退出吗?错误吗是多少,还是卡着不动。“另一种错误”是输出什么了。
    cominghome
        2
    cominghome  
       2021-05-19 11:14:56 +08:00
    加 -x 执行
    muzuiget
        3
    muzuiget  
       2021-05-19 11:53:17 +08:00
    看得头疼,用了 awk 和 except 已经不是单纯 shell,这两个工具算是有自己的语言多了,建议直接 Python 。
    guader
        4
    guader  
       2021-05-19 12:02:27 +08:00
    用 while read line do;;done<hostlist,然后 cut -d ' ' -f1,最后 expect 感觉会比较简单
    no1xsyzy
        5
    no1xsyzy  
       2021-05-19 12:10:37 +08:00
    建议直接 ansible

    或者 Python (考虑 plumbum )
    zhuisui
        6
    zhuisui  
       2021-05-19 12:51:30 +08:00
    建议你 expect 的脚本单独写文件,省的还要考虑字符串转换
    newaccount
        7
    newaccount  
       2021-05-19 13:17:38 +08:00
    看起来是在循环里面赋值造成的问题?
    不做太大改动的化,试试这种
    ```bash
    while read line; do
    IP=$(echo $line | awk '{print $1}')
    USER=$(echo $line | awk '{print $2}')
    PASS=$(echo $line | awk '{print $3}')
    echo $IP $USER $PASS
    done < $OLD_INFO
    ```
    mikaelson
        8
    mikaelson  
    OP
       2021-05-19 13:51:52 +08:00
    @jmyz0455 没法贴图我发帖的时候就没把故障贴上来 = =
    在循环里赋值的时候出错了,正常应该循环一次,赋值一次,他直接循环一次,把所有值都给赋值了。。错误大概如下。
    [root@localhost ~]# sh -x 1.sh
    + OLD_INFO=hostlist
    ++ awk '/^[^#]/{print $1}' hostlist
    + for IP in '$(awk '\''/^[^#]/{print $1}'\'' $OLD_INFO)'
    ++ awk -v I=192.168.128.131 'I==$1{print $2}' hostlist
    + USER='test
    a'
    ++ awk -v I=192.168.128.131 'I==$1{print $3}' hostlist
    + PASS='123456
    123456'
    ++ awk -v I=192.168.128.131 'I==$1{print $4}' hostlist
    + PORT='22
    22'
    no1xsyzy
        9
    no1xsyzy  
       2021-05-19 14:02:24 +08:00
    awk 就是扫全文,你每次都扫一遍全文,繁琐。
    直接写个 ansible playbook 不好吗?
    更轻量一点,用 pthon + plumbum 更形式化地调用命令不好吗?
    mikaelson
        10
    mikaelson  
    OP
       2021-05-19 14:12:50 +08:00
    @no1xsyzy 但是我好奇的是,为什么当 IP 不相同的时候,他能正常赋值呢? ip 相同的时候他反而就赋值出错了。。plumbum 还没玩过,我去百度研究看看= =谢谢。。
    mikaelson
        11
    mikaelson  
    OP
       2021-05-19 14:21:08 +08:00
    @newaccount 亲测可行。。。解决了我的疑惑,但是不懂为什么 for 循环会那样赋值了。。。
    no1xsyzy
        12
    no1xsyzy  
       2021-05-19 14:25:54 +08:00
    @mikaelson 我说得很清楚了,awk 每次重新打开 hostlist 并扫描其全文。
    mikaelson
        13
    mikaelson  
    OP
       2021-05-19 14:30:13 +08:00
    @no1xsyzy 多谢,我去研究看看你说的 plumbum
    iceecream
        14
    iceecream  
       2021-05-19 14:46:09 +08:00
    还在用这种老式的方法嘛。ansible 不香吗。
    mikaelson
        15
    mikaelson  
    OP
       2021-05-19 14:46:30 +08:00
    @iceecream 研究研究!!!毕竟就临时一个需求。
    no1xsyzy
        16
    no1xsyzy  
       2021-05-19 15:29:57 +08:00
    @mikaelson 主要 ansible 可以直接抄作业,工作量反而低一点,只是框架本身显得很重
    james122333
        17
    james122333  
       2021-05-19 22:21:37 +08:00
    因为同个 ip 就是 I==$1 会判断正确
    话说这脚本写的不是一般的差 效能差又不优雅
    mikaelson
        18
    mikaelson  
    OP
       2021-05-20 09:28:55 +08:00
    @james122333 有没有优雅的便捷方式 - -
    fo0o7hU2tr6v6TCe
        19
    fo0o7hU2tr6v6TCe  
       2021-05-20 10:06:55 +08:00
    for line in lines; do
    fo0o7hU2tr6v6TCe
        20
    fo0o7hU2tr6v6TCe  
       2021-05-20 10:14:39 +08:00
    #!/bin/bash

    while read line;do
    ip=$(echo $line | awk '/^[^#]/{print $1}')
    ip=$(echo $line | cut -d ' ' -f 1)
    echo $ip
    done < xx

    上一条自动回复了。。不好意思,顺便问一句,你这个 ssh 的 expect 是在控制老版本的交换机么
    blessingsi
        21
    blessingsi  
       2021-05-20 20:00:16 +08:00
    如果只是执行一行命令,推荐 sshpass,比 expect 简单多了。。
    james122333
        22
    james122333  
       2021-05-25 22:06:56 +08:00
    @mikaelson

    写更优雅的脚本
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     950 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 18:12 PVG 02:12 LAX 10:12 JFK 13:12
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86