ユーザー(ワイルドカード)ホームディレクトリにファイルをコピーするBashスクリプト

ユーザー(ワイルドカード)ホームディレクトリにファイルをコピーするBashスクリプト

/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

あなたは非常に才能があるので、私はスクリプトを提供しません。しかし、以下はいくつかのヒントです。

  1. awkあなたはそれを誤って使用しています。この試み:

    awk -F: -v uid_min=${UID_MIN:-1000} '$3%2==0 && $3>uid_min && $3!=65534{print $6}' /etc/passwd
    
  2. 必要ありませんcat

  3. awk出力をループの入力として使用しますreadwhile read USER_HOME_DIR ; do ... ; done < $(awk...)。これはawk1つのプロセスを作成するだけですが、ソーススクリプトは各行ごとawkに別々のプロセスを作成するため、より効率的であることを理解してください。

  4. awk1000を超えるUIDに制限するには、プログラムにチェックを追加します。それ以外の場合は、多くのシステムユーザーに対して誤ってコピーを実行します。

  5. 上記の#1では、ユーザー名の代わりにユーザーのホームディレクトリを抽出する$1ように変更しました。$6

  6. 私のDebianコンピュータにUID 65534を持つ「誰もいない」ユーザーがいることに気づいたので、これを検討してください。awkこれにより#1の説明を修正しました。

  7. ユーザー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 
  )

関連情報