最近在寫shell腳本的時候,涉及到一個使用shell腳本發送json數據的問題,就是發送的json數據雙引號不見了,致使數據格式不正確,收到了錯誤的響應。後來仔細查看了資料才發現本身以前對shell單引號和雙引號的理解有一些問題,在此記錄一些現象和結果。html
1.首先,我這邊使用的是bash腳本,放一下bash腳本的手冊地址;
2.而後咱們看一下官方的手冊裏面是怎麼介紹的:
2.1 單引號:node
Single Quotes: Enclosing characters in single quotes (‘'’) preserves the literal value of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash.
翻譯出來就是:用單引號(''')括起字符能夠保留引號中每一個字符的字面值。單引號之間可能不會出現單引號,即便前面有反斜槓也是如此。shell
個人理解是單引號中的值都是會直接輸出字符或這字符串的字面量,不會去解析各類變量或者其餘的符號,並且必須是成對出現的。若是兩個單引號之間有單引號,或者兩個單引號之間有反斜杆的單引號都是不會結束的狀況,必須等待新的單引號出現,讓它們成對了纔會結束。(__這裏的意思是bash的解釋器會對單引號去解析,只有成對的時候纔會結束,不然會一直等待,因此呢單引號對號都是成對的使用,雖然我也不知道單個的單引號有什麼用__)。
下面舉幾個栗子用來解釋一下剛纔說的:json
能夠看到前兩張圖,輸入了三個單引號,或者兩個單引號之間是一個帶反斜杆的單引號。都會出現>的符號,意思是等待繼續的輸入。第三張圖輸入了單引號之後,出現了;號,表示結束了。說明解釋器對單引號都是要成對的去解析。
2.2 雙引號:bash
Double Quotes Enclosing characters in double quotes (‘"’) preserves the literal value of all characters within the quotes, with the exception of ‘$’, ‘`’, ‘\’, and, when history expansion is enabled, ‘!’. When the shell is in POSIX mode (see Bash POSIX Mode), the ‘!’ has no special meaning within double quotes, even when history expansion is enabled. The characters ‘$’ and ‘`’ retain their special meaning within double quotes (see Shell Expansions). The backslash retains its special meaning only when followed by one of the following characters: ‘$’, ‘`’, ‘"’, ‘\’, or newline. Within double quotes, backslashes that are followed by one of these characters are removed. Backslashes preceding characters without a special meaning are left unmodified. A double quote may be quoted within double quotes by preceding it with a backslash. If enabled, history expansion will be performed unless an ‘!’ appearing in double quotes is escaped using a backslash. The backslash preceding the ‘!’ is not removed. The special parameters ‘*’ and ‘@’ have special meaning when in double quotes (see Shell Parameter Expansion).
大概意思是說:雙引號中的信息會保留字面量,可是同時會對$,`,,這些符號作出特殊的解析。就是雙引號中的變量和轉義,和函數操做能夠被正常解析出來。這個比較好理解,接下來咱們看下單引號和雙引號使用的一些栗子,加深一下咱們的理解。app
直接上圖:
輸出1,2,應該沒有什麼問題都是輸出的字面量的字符串。
輸出3,4,就是展現了單引號和雙引號的區別,單引號繼續輸出了字符串,而雙引號輸出了變量a的值。
輸出5,6呢,其實就是我遇到的問題,腳本中須要使用到日期的變量,而且放入到json的數據中。
輸出5若是直接使用單引號,確定行不通,由於不解析變量。
輸出6呢,雖然最外層使用了雙引號,內部能夠解析變量,可是發現問題沒有,變量外面是沒有雙引號的,而json的數據格式是{"key":"value"}。也是不符合的,__緣由在於shell解釋器分辨不出來雙引號是在第幾層,僅僅查到一堆雙引號就把它們結爲夫妻(一對對的雙引號進行解析),因此輸出6的解析過程是"'{"解析出'{,第二對雙引號":"解析出:,第三對雙引號"$start_date"解析出start_date的值,依次類推。得出了'{startDay:2019-03-31 00:00:00,endDay:2019-03-31 23:59:59}'__。
輸出7至關於就是正確的輸出了json格式的數據,原理也很簡單在輸出6已經解釋清楚。less
1.__寫shell腳本的時候,若是不須要解析裏面的內容,就使用單引號,反之,雙引號;__
2.__記住shell解析單引號和雙引號的規則,是就近原則,遇到一對單/雙引號,就會解析出其中的內容,而不是根據什麼最外層,最內層這種層級關係去解析的,這點要記住。因此在輸入json或者其餘的格式的數據的時候,混合使用單/雙引號的時候要注意使用的順序,不然獲得的結果並非你預想的那樣__函數