讀取命令刪除雙倍空格,只保留一個
我編寫了一個腳本,在本地機器上收集應用程序日誌,然後從遠端機器上收集。
它具有
oldlogsdate
讀取我要收集的日誌日期的變數。例如,如果我輸入
Apr 23
它可以正常工作,因為只有一個空格,但如果我輸入(和Apr 4
之間的兩個空格)它將刪除一個空格。Apr``4
注意:這
oldlogsdate
也是在使用者的遠端機器上設置的.bash_profile
,然後輸入的日期通過使用sed
命令進行更改。printf "\n";read -p "Which Date Logs you want to collect = " oldlogsdate ssh -qt remote-user-name@xxx.xxx.xxx.xxx "sed -i "s/oldlogsdate=.*/oldlogsdate=\'\"$oldlogsdate\"\'/" ~/.bash_profile" oldlogsdate="Apr 7"
現在為什麼我要使用它
Apr 23
,它是命令Apr 4
的一部分。ls
有沒有辦法在讀取命令中保留雙空格,或者其他更好的方法?
讀取命令刪除雙倍空格並只保留一個
它沒有。該
read
命令本身將內部空格保持原樣(但是,除非您設置IFS
為空,否則它將修剪前導和尾隨空格;如果您不使用,它也會破壞反斜杠-r
)。read myVar <<<'Apr 4' echo "$myVar" # will output: Apr 4
那就是由於沒有雙引號變數而失去空格的人:
myVar2='Apr 4' echo $myVar2 # will mangle spaces, please always use "$myVar2" instead
不正確引用變數不僅會使腳本行為不端,而且還可能引入潛在的安全風險。
更正確的命令是
ssh -qt remote-user-name@xxx.xxx.xxx.xxx "sed -i 's/oldlogsdate=.*/oldlogsdate=\"$oldlogsdate\"/' ~/.bash_profile"
但它不是通用的,也不安全,因為它沒有考慮到
$oldlogsdate
值可能不僅包含空格,還可能包含撇號、斜杠、反斜杠、美元符號和驚嘆號。
請注意您的
ssh
命令行,將sed
命令發送到另一端的部分:ssh ... "sed -i "s/oldlogsdate=.*/oldlogsdate=\'\"$oldlogsdate\"\'/" ~/.bash_profile" ^^^^^^^^^..................................................^^^^^^^^^^^^^^^^^^
這裡有兩個帶引號的字元串,標有
^
. 中間的其餘部分沒有被引用,其中包括變數擴展$oldlogsdate
。由於它沒有被引用,因此它受到分詞的影響,並Apr 7
成為兩個詞Apr
and7
。另請參閱:何時需要雙引號?現在,
ssh
它足夠聰明,可以將它們重新粘合在一起,但現在原始的空白量已經失去,它只是增加了一個空格。這有點類似於 shell 如何忘記其中的原始空格
echo
並將單詞與單個空格粘合在一起:$ echo hello world hello world
但請注意,對於 SSH,單級引號沒有幫助,因為 SSH 將命令行傳遞給遠端端的 shell 進行解釋,並且在該 shell 中,單詞之間的額外空格也會失去。
所以這仍然不起作用:
$ ssh localhost echo "hello world" hello world
(本地外殼刪除引號,並
ssh
獲取echo
和hello world
,並傳遞給遠端echo hello world
,它的工作原理如上。)我們實際上必須對兩端進行引用以保持字元串完整:
$ ssh localhost 'echo "hello world"' hello world
其實用 etc. 來更恰當地顯示單詞中斷的地方會更好
printf ":%s\n" hello world
,但結果是相似的。切換引號以使雙引號位於最外層,讓本地 shell 擴展變數,並將單引號留給遠端,這樣可以最大限度地減少它所做的擴展量。您仍然需要反斜杠轉義要發送到另一端的任何雙引號。
$ greeting="hello world" $ ssh localhost "echo '$greeting'" hello world
只要變數本身不包含單引號,這應該可以工作。如果是這樣,事情會變得更醜陋,請參閱:Escape a variable for use as content of another script
我認為@sasha 答案中的命令行看起來應該適用於您的情況。
另請參閱,例如這個問題:在 ssh 中引用 $ host $ FOO 和 ssh $ host “sudo su user -c $ FOO” 類型構造 手頭的問題還有一層處理,但答案似乎也適用於“更簡單”的情況*。*