Bash

僅當該行還不是文件的一部分時才在文件中插入一行

  • January 21, 2019

我正在尋找創建一個腳本來自動將一些自定義配置應用於基於文本的配置文件。

/etc/sysctl.conf在本例中,如果這些行尚未在文件中,我正在搜尋添加 2 行(以避免在文件中多次出現這些行)。

這是我使用的腳本:

if [ `grep vm.swappiness /etc/sysctl.conf` != "vm.swappiness=5" ]; then
echo vm.vfs_cache_pressure=50 | sudo tee -a /etc/sysctl.conf
fi
if [ `grep vm.vfs_cache_pressure /etc/sysctl.conf` != "vm.vfs_cache_pressure=50" ]; then
echo vm.vfs_cache_pressure=50 | sudo tee -a /etc/sysctl.conf
fi

和我得到的錯誤:

/home/erwan/Workspace/Install.sh: ligne 19 : [: != : opérateur unaire attendu
/home/erwan/Workspace/Install.sh: ligne 23 : [: != : opérateur unaire attendu

我究竟做錯了什麼?

這是個問題:

if [ `grep vm.swappiness /etc/sysctl.conf` != "vm.swappiness=5" ]; then

由於 ifgrep沒有找到任何東西,它不會輸出任何東西,並且 this 的左側將是空的,這是一個錯誤。如果它確實找到了某些東西,這也是一個問題,因為輸出可能包含空格(例如,如果vm.swappiness在文件中多次出現)。這需要被引用,否則它會在展開時顯示為一系列不同的字元串。

因此,您應該使用if [ "$(grep ...)" ]這樣的輸出被引用。如果沒有輸出,則有"",這在 bash 測試的任一側都可以。

但是,在這種情況下,我建議改用 grep 的退出狀態。來自man grep

退出狀態

通常,如果找到選定的行,則退出狀態為 0,否則為 1。但如果發生錯誤,退出狀態為 2…

這裡也有用的是-q開關:

-q,–安靜,–靜音

安靜的; 不要向標準輸出寫入任何內容。如果找到任何匹配項,即使檢測到錯誤,也會立即以零狀態退出。

因此,請記住$?最後完成的前台程序的退出狀態:

grep -q grep vm.vfs_cache_pressure /etc/sysctl.conf
if [ $? -eq 1 ]; then

grep如果沒有找到任何東西並且沒有發生錯誤,則此條件為真。

引用自:https://unix.stackexchange.com/questions/138744