/root/nbu/file1.sh
ユーザーのIDが偶数の場合は、各ユーザーのホームディレクトリにコピーする必要があります。
次のスクリプトを実行してみてください。
#!/bin/bash
cat /etc/passwd | while read LINE
do
username=$(awk -v var="$LINE" -F: '{
if ($3 % 2 == 0)
print $1
}')
cp /root/nbu/file1.sh ~"$username"
done
しかし、それは何もしません。コマンドをエコーしcp /root/nbu/file1.sh ~"$username"
てスクリプトから直接実行すると機能します。
~
bashスクリプトで問題が拡大しているようですが、この問題を解決する方法がわかりません。
よろしくお願いします。
答え1
ユーザー名部分が引用されている場合、チルダ拡張は効果がありません。
$ echo ~root ~"root"
/root ~root
(とにかく、変数拡張の前に発生します。)
しかし、passwd
シェルから読んだので、全体の内容を実行してみてはいかがでしょうか?
#!/bin/bash
getent passwd | while IFS=: read -r user pass uid gid gecos home shell; do
if (( uid % 2 == 0 )); then
echo "uid $uid of user '$user' is even and their home is '$home'";
fi;
done
システムにいる場合は、自分で使うgetent
よりもお勧めします/etc/passwd
。
一方、何も実行するのに実際にはユーザー名が必要ではないようですawk
。目次( $6
) 彼とは逆です。
答え2
その理由は変数拡張の前にチルダ拡張が行われます。:
拡張順序は、中かっこ拡張、引数と変数拡張、算術拡張、コマンド置換(左から右へ)です。
echo
計算結果そうだそうですね。再評価はうまくいきますが、スクリプトの場合は別の方法で行う必要があります。おそらく:
# ...
homedir=$(getent passwd "$username" | cut -d: -f6)
cp /root/nbu/file1.sh "$homedir"
# ...
答え3
あなたは非常に才能があるので、私はスクリプトを提供しません。しかし、以下はいくつかのヒントです。
awk
あなたはそれを誤って使用しています。この試み:awk -F: -v uid_min=${UID_MIN:-1000} '$3%2==0 && $3>uid_min && $3!=65534{print $6}' /etc/passwd
必要ありません
cat
。awk
出力をループの入力として使用しますread
。while read USER_HOME_DIR ; do ... ; done < $(awk...)
。これはawk
1つのプロセスを作成するだけですが、ソーススクリプトは各行ごとawk
に別々のプロセスを作成するため、より効率的であることを理解してください。awk
1000を超えるUIDに制限するには、プログラムにチェックを追加します。それ以外の場合は、多くのシステムユーザーに対して誤ってコピーを実行します。上記の#1では、ユーザー名の代わりにユーザーのホームディレクトリを抽出する
$1
ように変更しました。$6
私のDebianコンピュータにUID 65534を持つ「誰もいない」ユーザーがいることに気づいたので、これを検討してください。
awk
これにより#1の説明を修正しました。ユーザーJeff Schallerのコメントに基づいて、カスタム
awk
最小UIDを考慮するようにプログラムを変更しました。${UID_MIN:-1000}
このフォームは、値が元のnullまたは設定されていない場合、値を1000に設定します。
答え4
一文でできると思います。これを見てください:
eval $(awk -v source="/root/nbu/file1.sh" -v uid_min=${UID_MIN:-1000} -F: '$3%2==0 && $3>uid_min && $3!=65534{printf "cp %s %s ;", source, $6 }' /etc/passwd)
読みやすさのために:
eval $(
awk \
-v source="/root/nbu/file1.sh" \
-v uid_min=${UID_MIN:-1000} \
-F: '
$3%2==0 && $3>uid_min && $3!=65534 {
printf "cp %s %s ;", source, $6
}
' /etc/passwd
)