まだファイルの一部でない場合にのみ、ファイルに行を挿入します。

まだファイルの一部でない場合にのみ、ファイルに行を挿入します。

テキストベースの構成ファイルにいくつかのカスタム構成を自動的に適用するスクリプトを作成しようとしています。

/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

私は何が間違っていましたか?

答え1

これは問題です:

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

なぜならgrep何も見つからなければ何も出力せず、左にも何もないだろうからです。これはエラーです。出力にスペースが含まれる可能性があるため(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何も見つからず、エラーが発生しない場合、この条件はtrueです。

答え2

おそらくgrep何も返さないからです。参照されていないため、対応するエラーメッセージが表示されます(単項演算子が必要です)。努力する:-

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

答え3

インスピレーションを得るために少し調整が必要な場合があります。

#assuming there is only one line with vm.swappiness
#otherwise you can use the test command with "grep -c vm.swappiness" first
#tests if the correct line is in the file
if grep -q -E '^vm.swappiness=5$' /etc/sysctl.conf; then
    echo "all good, do nothing";
else
    echo "removing possible lines with vm.swappiness"
    sudo sed -i '/^vm.swappiness=/d' /etc/sysctl.conf 
    echo "adding line with correct swappiness"
    sudo bash -c "echo 'vm.swappiness=5' >> /etc/sysctl.conf"
fi

また、次の引数で呼び出すことができるように関数でラップすることをお勧めします。

答え4

これはうまくいくかもしれません:

f=/etc/sysctl.conf
[ -w "$f" ] || exit 1
for line in 'vm.swappiness=5' 'vm.vfs_cache_pressure=50' ; do
    grep -q "$line" <"$f" || printf %s\\n "$line"
done >>"$f"

sudoおそらくそのスクリプトも削除する必要があります。必要に応じてスクリプトを実行します。そして sudo[OK]sudo ./script.shをタップして、他のスクリプトとは別のモジュールとして使用してください。それ以外の場合は、次のようにします。

sudo sh -c '
    f=/etc/sysctl.conf
    [ -w "$f" ] || exit 1
    for line in "vm.swappiness=5" "vm.vfs_cache_pressure=50" ; do
        grep -q "$line" <"$f" || printf %s\\n "$line"
    done >>"$f"
'

しかし、私はそれをお勧めしません。

関連情報