ユーザーがbashシェルプロンプトでパスワードを入力し、そのパスワードをプログラムのstdinの一部にするための(1)最も安全で(2)最も簡単な方法を探しています。
これはstdinがどのように見える必要があるかです:{"username":"myname","password":"<my-password>"}
、 どこ <my-password>
は、シェルプロンプトに入力されたものです。プログラムstdinを制御できれば、パスワードを安全に要求して適切な場所に配置するようにプログラムを変更できますが、ダウンストリームは標準的な汎用コマンドです。
以下を使用するアプローチを検討し、拒否しました。
...$PASSWORD...
):パスワードは引き続き「ps」を介してすべてのユーザーに表示されます私は現在の解決策を以下の回答として示しますが、誰かが考え出した場合、より良い回答を喜んで選択します。もっと単純なものがあるべきだと思います。あるいは、誰かが私が見逃したセキュリティの懸念を見ているかもしれません。
bash
またはzsh
の場合:
unset -v password # make sure it's not exported
set +o allexport # make sure variables are not automatically exported
IFS= read -rs password < /dev/tty &&
printf '{"username":"myname","password":"%s"}\n' "$password" | cmd
IFS=
がない場合、read
は入力したパスワードから先頭と末尾の空白を削除します。
-r
がないと、バックスラッシュを引用文字として処理します。
ターミナルからのみ読み取ることを確認したいとします。
echo
は確実に使用できません。 bash
とzsh
にはprintf
が組み込まれているため、コマンドラインがps
の出力に表示されません。
bash
では、$password
を引用符で囲む必要があります。そうしないと、split + glob演算子が適用されます。
その文字列をJSONとしてエンコードする必要があるので、それはまだ間違っています。たとえば、少なくとも二重引用符とバックスラッシュは問題になります。これらの文字のエンコードについて心配する必要があるでしょう。プログラムはUTF-8文字列を期待していますか?端末は何を送信しますか?
zsh
を使用してプロンプト文字列を追加するには:
IFS= read -rs 'password?Please enter a password: '
bash
の場合:
IFS= read -rsp 'Please enter a password: ' password
これが私が持っている解決策です(テストされています):
$ read -s PASSWORD
<user types password>
$ echo -n $PASSWORD | Perl -e '$_=<>; print "{\"username\":\"myname\",\"password\":\"$_\"}"'
説明:
read -s
は、画面にエコーしないでstdin(パスワード)の行を読み取ります。シェル変数PASSWORDに格納されます。echo -n $PASSWORD
は、改行なしでパスワードをstdoutに書き込みます。 (echoはシェルの組み込みコマンドであるため、新しいプロセスは作成されないため、(AFAIK)echoの引数としてのパスワードはpsに表示されません。)$_
にパスワードを読み取ります$_
のパスワードをフルテキストに入れ、それを標準出力に出力しますこれがHTTPS POSTの場合、2行目は次のようになります。
echo -n $PASSWORD | Perl -e '$_=<>; print "{\"username\":\"myname\",\"password\":\"$_\"}"' | curl -H "Content-Type: application/json" -d@- -X POST <url-to-post-to>
お使いのバージョンのread
が-s
をサポートしていない場合は、 この答え にあるPOSIX互換の方法を試してください。
echo -n "USERNAME: "; read uname
echo -n "PASSWORD: "; set +a; stty -echo; read passwd; command <<<"$passwd"; set -a; stty echo; echo
passwd= # get rid of passwd possibly only necessary if running outside of a script
set +a
は、変数の環境への自動「エクスポート」を防止するためのものです。 stty
のmanページを確認してください。利用可能なオプションはたくさんあります。適切なパスワードにはスペースを含めることができるため、<<<"$passwd"
が引用されています。 stty echo
を有効にした後の最後のecho
は、次のコマンド/出力を新しい行で開始することです。