2016-02-08 88 views
0

我在bash中的printf函數遇到了一些麻煩。 我寫了一個小腳本,在其上傳遞名稱和兩個字母(如「sh」,「py」,「ht」),並在名爲「name.extension」的當前工作目錄中創建一個文件。 例如,如果我執行seed test py,將在當前工作目錄中創建一個名爲test.py的文件,其文件名是#!/usr/bin/python3Printf在空格處分割一個字符串 - Bash

到目前爲止,這麼好,沒有什麼幻想:我正在學習shell腳本,我認爲這可能是一個簡單的練習來測試迄今獲得的知識。 問題是當我想創建一個HTML文件。這是我使用的功能:

creaHtml(){ 
     head='<!--DOCTYPE html-->\n<html>\n\t<head>\n\t\t<meta charset=\"UTF-8\">\n\t</head>\n\t<body>\n\t</body>\n</html>' 
     percorso=$CARTELLA_CORRENTE/$NOME_FILE.html 
     printf $head>>$percorso 
     chmod 755 $percorso 

} 

如果我運行,例如,seed test ht正確的函數(creaHtml)被調用時,將創建test.html但如果我嘗試尋找到它,我只看到:

<!--DOCTYPE 

沒有別的。 這是該功能的跟蹤:

[sviluppo:~/bin]$ seed test ht 
+ creaHtml 
+ head='<!--DOCTYPE html-->\n<html>\n\t<head>\n\t\t<meta charset=\"UTF-8\">\n\t</head>\n\t<body>\n\t</body>\n</html>' 
+ percorso=/home/sviluppo/bin/test.html 
+ printf '<!--DOCTYPE' 'html-->\n<html>\n\t<head>\n\t\t<meta' 'charset=\"UTF-8\">\n\t</head>\n\t<body>\n\t</body>\n</html>' 
+ chmod 755 /home/sviluppo/bin/test.html 
+ set +x 

但是,如果我嘗試從終端運行printf '<!--DOCTYPE html-->\n<html>\n\t<head>\n\t\t<meta charset=\"UTF-8\">\n\t</head>\n\t<body>\n\t</body>\n</html>',我看到正確的輸出:在與縮進,一切都整齊地顯示一個HTML文件的「骨架」。我在這裏錯過了什麼?

+1

基本上,引用你的變量。不要使用'echo -e',因爲它是非標準的。當你添加引號時,'printf'會做你想要的。 –

+0

只要非常確定,我在引用變量時必須加雙引號,比如'printf「$ var1」',對不對? –

+1

雙引號將評估裏面的變量。單引號是不會被評估的文字。 – e0k

回答

1

嘗試echo -e而不是printfprintf用於打印格式化的字符串。由於您沒有用引號保護$head,因此bash將字符串拆分以形成命令。第一個單詞(在第一個空格之前)形成格式字符串。其餘的只是你沒有指定要打印的東西的參數。

echo -e "$head" > "$percorso" 

-e評估您\n成換行符。我將>>更改爲>,因爲它看起來像是希望它成爲整個文件,而不是附加到您可能擁有的任何現有文件。

你必須小心bash中的引號。有一件事可以變成許多事情。這實際上使得它更加強大,但它可能會讓人們感到困惑。請注意,我也將文件名"$percorso"也放在雙引號中。這會評估變量並確保它最終成爲一件事。如果你使用單引號,它將會是一個單詞,但不會被評估。與Python不同,單引號和雙引號之間存在很大差異。

如果你想使用printf兼容性作爲@chepner指出的那樣,只是一定要引用它:

printf "$head" > "$percorso" 

其實就是簡單得多呢。

+0

優秀!它像一個魅力。謝謝你的答案,只要我能接受你的答案,現在stackoverflow說,我可以在6分鐘內接受。 –

+2

''printf'被推薦超過'echo -e',如果只是作爲一個好習慣進入。從一個shell到另一個shell,'echo'的行爲差別很大,而'printf'的行爲是由POSIX定義的。 – chepner

+1

@chepner好點。我補充說。這樣做也更簡單。我應該在開始時這樣做。 – e0k