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

2021-05-19 10:46:59 +08:00
 mikaelson

#!/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 参数,又是另一种错误了。。。

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

或者 Python (考虑 plumbum )
zhuisui
2021-05-19 12:51:30 +08:00
建议你 expect 的脚本单独写文件,省的还要考虑字符串转换
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
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
2021-05-19 14:02:24 +08:00
awk 就是扫全文,你每次都扫一遍全文,繁琐。
直接写个 ansible playbook 不好吗?
更轻量一点,用 pthon + plumbum 更形式化地调用命令不好吗?
mikaelson
2021-05-19 14:12:50 +08:00
@no1xsyzy 但是我好奇的是,为什么当 IP 不相同的时候,他能正常赋值呢? ip 相同的时候他反而就赋值出错了。。plumbum 还没玩过,我去百度研究看看= =谢谢。。
mikaelson
2021-05-19 14:21:08 +08:00
@newaccount 亲测可行。。。解决了我的疑惑,但是不懂为什么 for 循环会那样赋值了。。。
no1xsyzy
2021-05-19 14:25:54 +08:00
@mikaelson 我说得很清楚了,awk 每次重新打开 hostlist 并扫描其全文。
mikaelson
2021-05-19 14:30:13 +08:00
@no1xsyzy 多谢,我去研究看看你说的 plumbum
iceecream
2021-05-19 14:46:09 +08:00
还在用这种老式的方法嘛。ansible 不香吗。
mikaelson
2021-05-19 14:46:30 +08:00
@iceecream 研究研究!!!毕竟就临时一个需求。
no1xsyzy
2021-05-19 15:29:57 +08:00
@mikaelson 主要 ansible 可以直接抄作业,工作量反而低一点,只是框架本身显得很重
james122333
2021-05-19 22:21:37 +08:00
因为同个 ip 就是 I==$1 会判断正确
话说这脚本写的不是一般的差 效能差又不优雅
mikaelson
2021-05-20 09:28:55 +08:00
@james122333 有没有优雅的便捷方式 - -
hzjseasea
2021-05-20 10:06:55 +08:00
for line in lines; do
hzjseasea
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 是在控制老版本的交换机么

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/777848

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX