2016-09-29 53 views
1

在bash/Ubuntu的,传递变量成ASCII艺术

如果有一个ASCII艺术品文件:“ASCII艺术”在以下

|__ __| ____|/ ____|__ __| 
    | | | |__ | (___ | | 
    | | | __| \___ \ | | 
    | | | |____ ____) | | | 
    |_| |______|_____/ |_| Client ${CLIENT_ID} 

反正有传递变量“ $ {CLIENT_ID}“每次我们称之为ascii-art?

我们称之为此刻方式:

cat ascii-art 

通过以下方式不起作用

1. cat ascii-art | CLIENT_ID="1" 

  • 添加一个在文件的第一行更多行“ascii-art”
  • . command_line_parse.sh -c ${CLIENT_ID} 
    
    |__ __| ____|/ ____|__ __| 
        | | | |__ | (___ | | 
        | | | __| \___ \ | | 
        | | | |____ ____) | | | 
        |_| |______|_____/ |_| Client ${CLIENT_ID} 
    

    然后

    cat ascii-art | CLIENT_ID="1" 
    

    可以在任何大师指教?谢谢。

    +0

    你不是在“呼唤”任何事情;这不是一个脚本。 Bash变量不能为模板系统创建一个合适的平台。 – chepner

    回答

    0

    首先:看节目figlet,toiletcowasy。这些可能已经完成了你想要的东西。

    如果你想自己动手写:

    sed 's/${CLIENT_ID}/42/g' ascii-art 
    
    +0

    真棒!这完美的工作,@ RotatingPieces! – Chubaka

    +0

    我们是否可以将“42”作为变量输入?此刻,如果我使用sed的/ $ {CLIENT_ID}/$ {CLIENT_ID_INPUT}/g'ascii-art,它会将“$ {CLIENT_ID}”替换为“$ {CLIENT_ID_INPUT}” – Chubaka

    +0

    使用“而不是”读取一些关于Linux shell引用的教程,不要忘了标记我的帖子为答案 – RotatingPieces

    1

    以下为文件的内容评估echo命令:

    CLIENT_ID=1000 eval "$(cat <<EOC 
    echo -e "$(<ascii-art)" 
    EOC 
    )" 
    
    • CLIENT_ID=1000分配环境变量为eval命令
    • eval接受此文档作为其单个参数
    • $(<ascii-art),在猛砸,不一样$(cat ascii-art)

    关于吓人eval

    这是真的,我们应该避免使用eval编辑。但我们也应该了解该命令的用途,并在适当的时候使用它。我们应该了解 的安全风险,并决定我们是否应该或在某些情况下不应该使用eval

    Bash Hackers Wiki给出了一个很好的描述eval

    也许去想EVAL最简单的方法是,它以同样的方式 工作方式从脚本运行bash -c "bash code…",除了在 的情况下eval,给定的代码在当前shell环境中执行而不是子进程 。

    所以eval只是执行我们传递的shell代码。我们多久执行一次Bash脚本的外部命令 ?我想,经常。而命令 只是可信的可执行文件,它们本身可能就是Bash脚本。

    那么为什么要害怕评估一些echo "trusted content"

    由用户(OP)决定在某些 的情况下使用eval是否安全。但是,这个答案肯定给了他一个选择;它是一个 替代解决方案。所以我不明白在这个答案downvote。

    +1

    这似乎是一个非常糟糕的主意,除非你事先知道'CLIENT_ID'和文件的内容 – chepner

    +0

    @chepner,well ,OP似乎都知道,这个文件显然是私有的,任何好的想法,btw? –

    +0

    如果“CLIENT_ID”的值已修复,则不需要对它所在的位置进行模板化。由于它不是固定的,因此假设攻击者永远无法操纵替代值是非常危险的:某人闯入系统的第一个目标之一是确定如何升级该访问。如果这是(比如说)一个提示信息打印给刚刚连接的用户,然后将它们放入一个非常有限的shell中,那么任何可以控制'CLIENT_ID'的错误都可以用来解决这些限制。 –

    0

    从RotatingPieces的回答修改上述

    首先修改 “ASCII艺术” 的文件,并更改 “$ {CLIENT_ID}” 到 “CLIENT_ID_ART”

    |__ __| ____|/ ____|__ __| 
        | | | |__ | (___ | | 
        | | | __| \___ \ | | 
        | | | |____ ____) | | | 
        |_| |______|_____/ |_| Client CLIENT_ID_ART 
    

    现在下面的方法可能并不很优雅,但它完美

    CLIENT_ID="1" # The ${CLIENT_ID} will actually be from the command line parser 
    
    echo "sed 's/CLIENT_ID_ART/"${CLIENT_ID}"/g' ascii-art > call_art 
    
    chmod +x call_art 
    
    ./call_art & 
    
    rm -f call_art 
    

    上面会打印出下面的输出

    |__ __| ____|/ ____|__ __| 
        | | | |__ | (___ | | 
        | | | __| \___ \ | | 
        | | | |____ ____) | | | 
        |_| |______|_____/ |_| Client 1 
    
    1

    envsubst工具出于这样的目的写:

    CLIENT_ID=foo envsubst ascii-art 
    

    这是一个最好的工具来sed,这限制了可能的值的范围(如果你有你的ID的/,甚至更糟一个分号后跟另一个sed命令,可能会发生严重的错误)。


    TemplateFiles参见有关Wooledge wiki,它包括用于无GNU gettext的系统的本机-bash的实现(包括envsubst)。