ファイルを1行ずつ繰り返し、各行を変数としてコマンドを実行する単純なシェルスクリプトを作成しようとしています。
これは私のテキストファイルです。
FakeAccount
FakeUser
これは私のシェルスクリプトです。
#!/bin/bash
while IFS= read -r line; do
"echo -e 'testpassword\ntestpassword' | passwd $line"
done < "User.txt"
私が得た出力は私が望むようです。出力は次のとおりです。
"ライン 4: echo -e 'testpasswd\ntestpasswd' | passwd FakeAccount: コマンドが見つかりません。"
"ライン 4: echo -e 'testpasswd\ntestpasswd' | passwd FakeUser: コマンドが見つかりません。"
しかし、次の文字列を正確にコピーすると、echo -e 'testpasswd\ntestpasswd' | passwd fake user
コマンドはうまく動作しますが、なぜシェルスクリプトがコマンドを実行してその内容を見つけることができないのですか?
答え1
コマンドとその引数を二重引用符で囲むと、文字列全体が単一のコマンドとして表示され、シェルが示すように見つかりません。
シェルは、コマンドのリスト、割り当て、コマンド、およびその引数を見つけるためにトークン化を実行する必要があります(man bash
詳細については、冒頭を参照)。
パイプ全体に二重引用符を使用せず、変数のみを引用します。
echo -e 'testpassword\ntestpassword' | passwd "$line"
答え2
以下を使用すると、これを簡単に行うことができますchpasswd
。
while read -r user; do printf "$user:%s" "some_secret_pass" | chpasswd ; done < User.txt
またはを使用するには、対応するフラグをpasswd
渡す必要があります。--stdin
私が知っている限り、最近のFedoraとCentosのバージョンはこれをサポートしています。
使用passwd
:
while read -r user; do printf %s\\n "some_secret_pass" | passwd --stdin "$user" ; done < User.txt