< cmds.txt'的内容如下:
ssh -o "StrictHostKeyChecking no" adamH@K1201.myhost.cn "/usr/bin/whoami"
ssh -o "StrictHostKeyChecking no" alexB@K1202.myhost.cn "/usr/bin/whoami"
ssh -o "StrictHostKeyChecking no" adamR@K1203.myhost.cn "/usr/bin/whoami"
ssh -o "StrictHostKeyChecking no" kevinC@K1204.myhost.cn "/usr/bin/whoami"
ssh -o "StrictHostKeyChecking no" rajE@K1205.myhost.cn "/usr/bin/whoami"
我试图在提示符中遍历此文件并分别执行它们。我的命令是:
export IFS=$'\n'; for i in `cat cmds.txt`; do $i; done
但它抱怨 bash:ssh -o" StrictHostKeyChecking no" maxK@K1261.myhost.cn" / usr / bin / whoami":没有这样的文件或目录。
我有什么遗失的吗?非常感谢。
答案 0 :(得分:4)
Don't put entire commands in variables和don't loop over lines with for
。简单直接的解决方案是仅分解那些实际变化的参数。
while read user_host; do
ssh -o "StrictHostKeyChecking no" "$user_host".myhost.cn /usr/bin/whoami
done <<'____HERE'
adamH@K1201
alexB@K1202
adamR@K1203
kevinC@K1204
rajE@K1205
____HERE
答案 1 :(得分:3)
为什么不使用source
?
source cmds.txt
甚至更短:
. cmds.txt
答案 2 :(得分:2)
由于您已将IFS
设置为仅换行符,因此当它在$i
上进行分词时,它只会在换行符时将其拆分,这些空格不再被视为分隔符。因此整行作为命令名,而不是参数后跟的命令。
但是如果你解决了这个问题,它仍然无法工作,因为扩展变量后不会处理引号。您需要使用eval
来完成所有命令解析规则。
IFS=$'\n'; for i in `cat cmds.txt`; do eval "$i"; done
但您可以这样做,而不是使用for
并且必须设置IFS
:
while read -r i; do eval "$i"; done < cmds.txt
答案 3 :(得分:0)
将命令放在变量中并不是一个好主意,但如果您想以任何方式执行,那么您可以这样做:
while IFS= read -r line; do
${line[*]}
done <cmds.txt
注意:不要在变量$line
("$line"
或"${line[*]}"
)中使用引号。它不会为这个案子工作。
在避免使用eval
的同时使用现有代码的一种方法可能是:
IFS=$'\n'
for i in `cat cmds.txt`; do #use of $(<cmds.txt) is better than `cat cmds.txt`
bash <<EOF
${i[*]}
EOF
done
注意:建议不要使用cat
和for
来读取文件中的行,而是使用while
循环。