'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 "StrictHostKeyCheck no"maxK@K1261.myhost.cn"/usr/bin/whoami":没有这样的文件或目录。
我错过了什么吗?多谢。
不要将整个命令放在变量中,也不要用 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
你为什么不直接使用source
?
source cmds.txt
甚至更短:
. cmds.txt
由于您已将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
<</div>
div class="one_answers"> 将命令放在变量中不是一个好主意,但如果你想以任何方式做到这一点,那么你可以这样做:
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
循环。