3つのタスクを実行するmakeスクリプトがあります。
- MySQLデータベースのインポート
- モバイルプロフィール
- 構成ファイルの構成
このためには、スクリプトには3つの入力が必要です。
- MySQLホスティング
- MySQLユーザー名
- MySQLパスワード
なぜかread
入力するたびに正しい変数に保存されますが、内容は私が保存した変数名で、最初の文字はありません。なぜこれが起こるのか分からないようです。
これはMakefile
:
SHELL := /bin/bash
default:
@echo "Welcome!";\
echo -n "Please enter the MySQL host (default: localhost):";\
read host;\
host=${host:-localhost};\
echo -n "Please enter the MySQL username:";\
read username;\
echo -n "Please enter the MySQL password:";\
read -s password;\
mv includes/config.php.example includes/config.php 2>/dev/null;true;\
sed 's/"USER", ""/"USER", "$(username)"/g' includes/config.php > includes/config.php;\
sed 's/"PASSWORD", ""/"PASSWORD", "$(password)"/g' includes/config.php > includes/conf$
echo $username;\
echo $password;\
mysql -u "$username" -p"$password" codeday-team < ./codeday-team.sql;\
echo "Configuration complete. For further configuration options, check the config file$
exit 0;
出力は次のとおりです
Welcome!
Please enter the MySQL host (default: localhost):
Please enter the MySQL username:<snip>
Please enter the MySQL password:sername
assword
ERROR 1045 (28000): Access denied for user 'sername'@'localhost' (using password: YES)
Configuration complete. For further configuration options, check the config file includes/config.php
ご覧のとおり、 が出力sername
されますassword
。これは一生修理できません!
この投稿の目的はread
バグを解決することですが、提案、バグレポート、または提案があれば感謝します。私は彼らに報酬を与えることができます。
ご協力ありがとうございます!
答え1
make
そこにシェルと変数を混ぜています。make
シェルとその両方が対応$
する変数を使用します。
Makefileでは、変数は単一文字変数または$(var)
シェルに表示されます。$v
$var
${var}
$var
しかし、Makefileに書くとmake
理解されます$(v)ar
。リテラルをシェルに渡すには、 in または で$
入力しなければシェルの or になります。$$
$$var
$${var}
$var
${var}
またmake
、実行するsh
とbash
コード(編集する、上記を見逃して申し訳ありません。多くのシステムにはまったく含まれSHELL := /bin/bash
ていないので(GNUのみの場合)、その構文を使用する必要があります。 、/文法ではなく構文ではありません。bash
/bin
bash
:=
sh
echo -n
read -s
zsh
bash
sh
zsh
これを行うには、/bash
スクリプトを追加してビルド依存関係を追加することをお勧めしますbash
。それは次のとおりです。
#! /usr/bin/env bash
printf 'Welcome\nPlease enter the MySQL host (default: localhost): '
read host || exit
host=${host:-localhost}
printf "Please enter the MySQL username: "
read username || exit
printf "Please enter the MySQL password:"
IFS= read -rs password || exit
printf '\n'
mv includes/config.php.example includes/config.php 2>/dev/null
repl=${password//\\/\\\\}
repl=${repl//&/\\&}
repl=${repl//:/\\:}
{ rm includes/config.php &&
sed 's/"USER", ""/"USER", "'"$username"'"/g
s:"PASSWORD", "":"PASSWORD", "'"$repl"'"/g' > includes/config.php
} < includes/config.php || exit
mysql -u "$username" -p"$password" codeday-team < ./codeday-team.sql || exit
echo "Configuration complete. For further configuration options, check the config file"
より多くの問題を解決します。
-r
ユーザーがパスワードにバックスラッシュを使用できるようにするには、パスワードを読むときにこれを行う必要があります。IFS=
ユーザーがスペースで始まるパスワードまたは終了するパスワードを持つことを許可するには、次のものが必要です。- ユーザー名にも同じことが当てはまりますが、ここではユーザーがユーザー名に愚かなものを使用せず、空白の削除とバックスラッシュの処理を/ feature /と見なすことができると仮定します。
- あなたの
;true
努力はmv
あなたが思うように行われません。errexit
このオプションの効果は取り消されません(make
呼び出しシェルを使用する実装の場合-e
)。あなたに必要なのはです||true
。ここではerrexit
、必要に応じて独自のエラー処理を使用または実行しません|| exit
。 &
バックスラッシュとs:pattern:repl:
区切り記号(ここ)を避ける必要があります:
。それ以外の場合は機能しません(そして不快な副作用があるかもしれません)。sed ... < file > file
始める前に切り捨てるため、これを行うことはできませんfile
。sed
いくつかのsed
実装は-i
or-i ''
オプションをサポートしています。または。perl -pi
perl -pi
ここを使うともっといいと思います。はい1 つは入力、最後の 1 つは出力です。
それでも質問は解決されません。
config.php
現在の権限から派生した権限で新しい権限が作成されますumask
。世界中で読むことができる実行中のユーザーが所有しますmake
。ディレクトリが特に制限されていない場合、umask
ファイルに機密情報が含まれているため、所有権を調整および/または変更する必要があります。includes
- パスワードに
"
文字が含まれていると、パスワードが破損している可能性があります(今回はphp
)。エラーを返してこれを抑制するか、php
そのファイルの正しい構文で別のエスケープレイヤーを追加しようとします。バックスラッシュと同様の問題が発生する可能性があり、ASCII以外の文字または制御文字を除外することもできます。 コマンドラインからパスワードを渡すことは、通常
mysql
パスワードが出力に表示されることを意味するので、それは悪い考えですps -f
。使用するのが最善です。mysql --defaults-file=<( printf '[client]\nuser=%s\npassword="%s"\n' "$username" "$password") ...
printf
組み込みのためps
出力には表示されません。$host
この変数は使用されません。- ユーザーにこのようなメッセージを表示することは、スクリプトを簡単に自動化できないことを意味します。パラメータから入力を取得するか、環境変数を使用できます(パスワードに適しています)。
答え2
Makefileのどの機能も使用していません。単一のシェルにこれらの行を書き込もうとしますか?
次のMakefileで
echo $username;\
echo $password;\
makeは(空の変数)+(文字列)$username
として解釈されます。$u
sername
Makefileに保存したい場合$username
。$$username