2016-09-29 88 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)。