File1.txt 包含主机列表:
computer_1
computer_2
File2.txt 包含命令列表...
ping host_name -c 10
dig host_name A host_name AAAA +short
...在主机上执行。在执行命令之前,将 file2 中的字符串sed -e "s/host_name/$line/" $2
替换host_name
为 File1 中的实际主机名。我最终得到:
ping computer_1 -c 10
dig computer_1 A computer_1 AAAA +short
ping computer_2 -c 10
dig computer_2 A computer_2 AAAA +short
如何将此输出作为命令执行?
我尝试了几种不同的新手方法,但均未成功,包括:
while read line; do
commands="$(sed -e "s/host_name/$line/" $2)"
eval $commands
done < $1
答案1
我怀疑这只是引号中的引号未按预期工作的问题。
代码的语法突出显示会提示正在发生的情况。请注意,s/host_name/$line/
绳子的其余部分是黑色的,而不是红色的?这是因为您实际上创建了两个字符串,其中包含一些 bash 无法理解的垃圾。
像这样的东西应该有效
while read line; do
commands=$(sed -e "s/host_name/$line/" $2)
eval "$commands"
done < $1
答案2
你可以同时拥有 awhile read loop
和 afor loop
Afoor loop
但它需要mapfile
又名readarray
mapfile -t commands < file2.txt
mapfile -t hosts < file1.txt
for h in "${hosts[@]}"; do
for c in "${commands[@]}"; do
echo command "$c" "$h"
done
done
如果你的 bash 还不够新,一个常见的解决方法是mapfile
IFS=$'\n' read -rd '' -a array < file.txt
或者
while IFS= read -r file; do
array+=("$file")
done < file.txt
现在"${array[@]}"
保存所有值/元素。
一个while read
循环。
while IFS= read -ru "$fd" h; do
while IFS= read -r c; do
echo command "$c" "$h"
done < file2.txt
done {fd}< file1.txt
echo
如果您认为输出正确,请删除,这样它才能真正执行命令。假设这两个文件每行都有一个条目,内置
command
应该就足够了,这意味着每行不需要;
分隔多个命令。其他方面是的...eval
$fd
and是一个任意名称{fd}
并使用任意文件描述符,如果您的 bash 还不够新,无法将其更改为3
或更高,因为0
to2
已被采用。需要使用不同的fd
,以防while read
循环中的某些东西正在吃/吸食,stdin
例如ssh
。