BASH读了一条线但只评估了一部分

时间:2014-12-22 12:10:51

标签: bash

我尝试逐行读取文件,并在新文件中对它们进行评估后编写每一行。

代码就是这样:

while read line
do
    if [[ $line =~ "<"*">" ]]
    then
      echo $line > bew_file.txt
    fi
    eval echo $line > test.txt
done < file.txt

在file.txt中,它通常是一个apache conf文件。

Alias /access "$VID"/
<Directory "$VIDEOREP">
    <IfVersion >= 2.4>
        Require all granted
    </IfVersion>
    <IfVersion < 2.4>
        Order allow,deny
        Allow from all
    </IfVersion>
    Header set Content-Disposition "attachment"
</Directory>

如果eval echo<*>一起发生,我会收到如下错误:

  

目录:没有这样的文件或目录

所以我把这个条件:if [[ $line =~ "<"*">" ]]放到<*>没有评估的行,但现在$VIDEOREP不能有值..

我如何读取<*>的行并评估该行内的值?

编辑:我无法触摸file.txt

2 个答案:

答案 0 :(得分:2)

正确引用您的变量也不需要特殊情况<*>字符串,这无论如何都是不完整的安全措施;还有很多其他字符串可以在你不加引号时使用它们来解决各种错误。

while read -r line; do
    eval echo "'$line'"
done <file.txt >bew_file.txt

(我假设你想要所有输出到同一个文件,而不是两个不同的文件,其中每个文件只包含生成输出的最后一行。)

然而,这还有许多其他问题。我的建议是只更换你真正想要替换的变量并删除eval

sed "s%\$VIDEOREP%$VIDEOREP%g;s%\$VID%$VID%g" file.txt >bew_file.txt

答案 1 :(得分:1)

一个有趣的可能性就是使用它:

#!/bin/bash

VID="vid_replacement"
VIDEOREP="video_replacement"

. <(cat <<EOF
cat <<EOF2
$(< file.txt)
EOF2
EOF
)

唯一的限制是你不能拥有这条线

EOF2
file.txt中的

,但这不太可能。当然,任意代码执行都是可能的,例如,如果您的文件包含$(ls),但这可能是一个功能......只需确保您是生成文件file.txt的人;如果文件来自不受信任/恶意的用户,请不要运行此文件。


会发生什么?

流程替换中的cat

cat <<EOF
cat <<EOF2
$(< file.txt)
EOF2
EOF

将输出到stdint以下内容:

cat <<EOF2
Alias /access "$VID"/
<Directory "$VIDEOREP">
    <IfVersion >= 2.4>
        Require all granted
    </IfVersion>
    <IfVersion < 2.4>
        Order allow,deny
        Allow from all
    </IfVersion>
    Header set Content-Disposition "attachment"
</Directory>
EOF2

然后这是 sourced (感谢. <( ... )术语),在这种情况下,here-doc的内容受参数扩展,命令替换和算术扩展的影响:正是你想要的。