我正在尝试将两个包含名称(如果有)和电子邮件的列表与bash(外壳)中的标准电子邮件文本合并 (我必须删除不相关的代码,因为其中包含一些私人信息,因此其中一些代码可能看起来并不有用。)
代码的前半部分检查是否有名称列表和电子邮件列表。 如果没有可用的名称,后半部分将仅合并电子邮件地址和文本;如果可用的名称列表,则还会“尝试”合并名称,电子邮件和文本。
f1 =电子邮件列表,f2 =姓名列表。 正如您在下面的代码的前半部分看到的那样,如果列表可用,则$ f2应该显示名称,但是在日志文件中则不显示任何内容。
我一直在努力解决此问题两天,但没有任何效果。当名称可用时,它总是输出为“ Hello ...” ,而应为“ Hello John D ...”
#FIRST HALF
if [ "$names" = "no" ]
then
text="Hello..."
elif [ "$names" = "yes" ]
then
text="Hello $f2..."
fi
#SECOND HALF
if [ "$names" = "no" ]
then
for i in $(cat $emaillist); do
echo "$text" >> /root/log
echo "$i" >> /root/log
done
elif [ "$names" = "yes" ]
then
paste $emaillist $namelist | while IFS="$(printf '\t')" read -r f1 f2
do
echo "$text" >> /root/log
echo "$f1" >> /root/log
done
fi
答案 0 :(得分:0)
运行text="Hello $f2"
时,在分配时会在{em>上查找$f2
;精确的字符串已分配给text
,以后仅在echo "$text"
上使用该精确的字符串。
这是非常可取的行为:如果shell变量的值可以运行任意代码,则不可能编写可以安全地处理不受信任数据的shell脚本...但这确实意味着实现程序需要进行一些更改。
如果您要推迟评估(在扩展时查找$f2
的值而不是赋值),请不要完全使用shell变量:请改用函数。
case $names in
yes) write_greeting() { echo "Hello $name..."; };;
*) write_greeting() { echo "Hello..."; };;
esac
while read -r name <&3 && read -r email <&4; do
write_greeting
echo "$email"
done 3<"$namelist" 4<"$emaillist" >>/root/log
上面的代码中的一些增强功能:
paste
即可同步地从两个流中读取数据;您可以简单地在不同的文件描述符上打开它们(上面已选择了FD 3
和4
;仅保留了0、1和2,因此也可能选择了更大的数字),并使用单独的{ {1}}命令。read
之后)比每次您想写一行都重新打开输出接收器效率更高。done
和"$namelist"
之类的扩展名;如果处理带有不寻常字符(包括空格和glob表达式)的文件名,或者"$emaillist"
为非默认值,这将使代码更加可靠。