設定値を上書きするには、パスワード(cat)をsedに渡します。

設定値を上書きするには、パスワード(cat)をsedに渡します。

以下を含む構成ファイルがあります.env

DB_PASSWORD={password}

その中には/root/.mysql/db00.yml.dbMySQL rootアカウントのパスワードがあります。sed次を介して渡そうとします。

cat /root/.mysql/db00.yml.db | sed -i -e "s/DB_PASSWORD=/DB_PASSWORD=(.*)/g" .env

運が悪く、次のようないくつかのバリエーションを試しました。

sed -i "s/DB_PASSWORD=/DB_PASSWORD=$(cat /root/.mysql/db00.yml.db)" .env
mysqlpwd=$(cat /root/.mysql/db00.yml.db)
# Use the variable in sed -i
sed -i "s/DB_PASSWORD=/DB_PASSWORD=$mysqlpwd/g" .env

これによりエラーが発生します。

root@linuxbox:/var/www/www.example.com# mysqlpwd=$(cat /root/.mysql/db00.yml.db)
root@linuxbox:/var/www/www.example.com# sed -i "s/DB_PASSWORD=/DB_PASSWORD=$mysqlpwd/g" .env
sed: -e expression #1, char 33: unknown option to `s'

修正する:

以下を実行しなくても失敗します/g

root@linuxbox:/var/www/www.example.com# echo $mysqlpwd
Rjcr/Sn+s/a2QbGx
root@linuxbox:/var/www/www.example.com# cat .env | grep DB_PASSWORD
DB_PASSWORD=(.*)()
root@linuxbox:/var/www/www.example.com# sed -i "s/DB_PASSWORD=/DB_PASSWORD=$mysqlpwd/" .env
sed: -e expression #1, char 33: unknown option to `s'

これらの方法のどれも動作しないようです。

私はsed 4.7それを実行しています:

root@linuxbox:/var/www/www.example.com# sed --version
sed (GNU sed) 4.7

答え1

本質的に、パスワードは以下を許可する必要があります。キーボードが安定して生成できるすべての文字。これは、編集スクリプトsedに挿入されたときにスクリプトをsed破損したり、システム上の任意のファイルに書き込んだり、GNUを使用して任意のコマンドを実行したりするための有効なコードまたは文字列をパスワードに簡単に含めることができることを意味しますsed(ルートとして実行すると)。

ユーザー提供のデータを使用する必要がある場合は、sedデータを整理する方法を正確に知らない限り使用しないでください。私は、シェルが私がほとんど制御できない変数を拡張できるように、二重引用符式(一重引用符の代わりに)を必要とするsedすべてを避けたいと思います。sed

代わりに、以下を使用してくださいawk

awk -F '=' '
    BEGIN { OFS = FS }
    NR == FNR { password = $0; next }
    $1 == "DB_PASSWORD" { sub("=.*",""); $2 = password }; 1' /root/.mysql/db00.yml.db .env >.env.new &&
mv .env.new .env

最初のファイルの最初の行からパスワードを読むことから始めます(ファイルにパスワードがそのまま含まれる1行だけが含まれているとします)。

次に、ファイルを.env区切りフィールドで構成されたファイルとして扱います。=

行の最初のフィールドがある場合は、DB_PASSWORD行の最初のフィールド=の後のすべての項目を消去し(以前のパスワードが含まれている場合=)、パスワードを2番目のフィールドに挿入します。

変更するかどうかにかかわらず、すべての行がとして出力され、ファイルは.env.new前の行.envに置き換えられますmv

決定的に、私は2つのファイルから読み取ったデータを次のように使用しません。パスワード私のプログラムでは、パスワードのどの部分も特別に扱うことを決してawk許可しません。awk呼び出し時に代替文字列としてパスワードを使用すると、sub()問題が発生する可能性があります。これは、&文字列のすべての内容が特殊文字列として扱われるためです。

答え2

sedで別の区切り文字を試してください...実際のパスワードによってはまだ失敗する危険があります(例:|または&または\1)。

sed -i "s|DB_PASSWORD=|DB_PASSWORD=$mysqlpwd|" .env

答え3

コマンドライン引数にパスワードを入力しないでください。システム内のすべてのユーザーが、1つps以上topの他の方法でパスワードを読み取ることができます。一部の自動化シナリオでは、これは可能性が低い可能性があることを知っています(誰もボックスにログインする可能性がないため)。しかし、それはまだ悪い考えであり、いくつかの監視ツールや他の人のいくつかのスクリプトがログに発生する可能性が常にあります。特定の時点でシステム上で実行されているプロセスを実行して、どこにいるかを知っている人にパスワードを記録します。

を使用して素晴らしい答えを得ました。共有に使用するawk簡単なソリューションも作成しました。exこれは特殊文字を含むすべてのパスワードに適用されます。唯一の例外は次のとおりです。終わりバックスラッシュで。

ファイルに以下が.env含まれている場合:

somevar1=someval
somevar2=some other val
DB_PASSWORD=
somevar3=another val
somevar4=val

以下myscriptを含みます。

/^DB_PASSWORD=$/a
!@#$#% some complicated password "^$%^&@#,.,cmxz\k'dvok][
.
0//j!
x

ただ実行すると、ex .env < myscript次のような結果が得られます。

$ ex .env < myscript
$ cat .env
somevar1=someval
somevar2=some other val
DB_PASSWORD=!@#$#% some complicated password "^$%^&@#,.,cmxz\k'dvok][
somevar3=another val
somevar4=val
$ 

答え4

sed -i -e "
  /^DB_PASSWORD=/c\\
DB_PASSWORD=$(sed -e 's:[\\]:&&:g' /root/.mysql/db00.yml.db)
"  ./.env
  • 変更コマンドに挿入された値を確保するために、sedコード自体にパスワード削除機能を組み込んでいます。c\

関連情報