バッチ処理を使用して一部のユーザーアカウントパスワードを設定しようとしていますchpasswd
。パスワードはランダムに作成され、印刷され、stdout
(書き留めまたはパスワードストアに入れる必要があります)、また渡されなければなりませんchpasswd
。
無邪気に私はこれをします
{
echo student1:$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13 ; echo '')
echo student2:$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13 ; echo '')
} | tee >(chpasswd)
ただし、新しいパスワードをコマンドライン引数として渡すのは心配ですecho
。引数は通常、他のユーザーに表示されるためですps -aux
(ただし、echo
どの行も表示されませんがps
)。
返されたパスワードの前に値を追加してから渡す他の方法はありますかchpasswd
?
答え1
echo
コードはシェルに組み込まれているため、プロセステーブルには表示されないため、安全でなければなりません。
代替ソリューションは次のとおりです。
#!/bin/bash
n=20
paste -d : <( seq -f 'student%.0f' 1 "$n" ) \
<( tr -cd 'A-Za-z0-9' </dev/urandom | fold -w 13 | head -n "$n" ) |
tee secret.txt | chpasswd
n
これにより、コマンドを使用してコマンドラインにパスワードを渡すことなく、生徒の名前とパスワードが生成されます。
このpaste
ユーティリティは、複数のファイルを列にまとめてファイル間に区切り文字を挿入します。ここでは区切り文字として使用:
し、2つの「ファイル」(手続き型置換)を提供します。最初にはseq
20の学生ユーザー名を生成するコマンドの出力が含まれ、2番目には長さ13の20のランダム文字列を生成するパイプラインの出力が含まれています。
生成されたユーザー名を含むファイルがある場合:
#!/bin/bash
n=$(wc -l <usernames.txt)
paste -d : usernames.txt \
<( tr -cd 'A-Za-z0-9' </dev/urandom | fold -w 13 | head -n "$n" ) |
tee secret.txt | chpasswd
secret.txt
生成されたパスワードを端末に表示するのではなく、パスワードとユーザー名をファイルに保存します。
答え2
echo
おそらくシェルに組み込まれているので、ps
別のプロセスとして表示されません。
ただし、コマンド置換を使用する必要はなく、パイプの出力を次に直接送信できますchpasswd
。
{ printf "%s:" "$username";
head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13 ; echo ''
} | chpasswd
一度に複数のパスワードを変更するには、chpasswd
基本部分を簡単に繰り返す必要があります。または関数に置き換えてください。
genpws() {
for user in "$@"; do
printf "%s:" "$user";
head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13
echo
done
}
genpws username1 username2... | chpasswd
ところで:ライン指向ではないhead /dev/urandom
ので、ちょっと変に感じられます。urandom
あまりにも多くのバイトを読み取ると、カーネルの利用可能なエントロピーの概念に影響を与え、ブロックが発生する可能性が/dev/random
あります。固定量のデータを読み取り、base64
任意のバイトを印刷可能な文字に変換するなどの方法を使用する方がよりきれいになる可能性があります(得られたバイトの約3/4を捨てる代わりに)。
このようなものはあなたにおおよそのものを与えるでしょう。 16文字と数字:
head -c 12 /dev/urandom | base64 | tr -dc A-Za-z0-9
(つまり、 の出力から と文字数を引く+
。残します。)/
base64