私はしばらくこの質問に対する答えを見つけようとしました。 awk出力に基づいてコマンドを実行するクイックスクリプトを作成しています。
ID_minimum=1000
for f in /etc/passwd;
do
awk -F: -vID=$ID_minimum '$3>=1000 && $1!="nfsnobody" { print "xfs_quota -x -c 'limit bsoft=5g bhard=6g $1' /home "}' $f;
done
問題は、パラメータ-c
がコマンドを一重引用符で囲んで正しくエスケープする方法を知らず、$1
ユーザー名にも拡張されないことです。
本質的に私はそれを出力したいと思います:
xfs_quota -x -c 'limit bsoft=5g bhard=6g userone' /home
xfs_quota -x -c 'limit bsoft=5g bhard=6g usertwo' /home
など...
答え1
xfs_quota -x -c 'limit bsoft=5g bhard=6g USER' /home
少なくともUIDを持つすべてのユーザーに対してUSER
コマンドを実行するには$ID_minimum
走る実行するコマンドを表す文字列を生成するのではなく、コマンドを実行します。
これは、コマンド文字列を生成した場合に生成する必要がありますeval
。これは退屈でエラーが発生しやすいです。ユーザー名のリストを取得し、コマンドを実行する方が良いでしょう。
getent passwd |
awk -F: -v min="${ID_minimum:-1000}" '$3 >= min && $1 != "nfsnobody" { print $1 }' |
while IFS= read -r user; do
xfs_quota -x -c "limit bsoft=5g bhard=6g $user" /home
done
実際には必要ありません。一つ後の引数は引用符で囲まれています-c
。ここでは$user
、extract値を含む変数をシェルが拡張したいので、二重引用符を使用していますawk
。
命令が変数に${ID_minimum:-1000}
値を割り当てるときに使用します。変数が空であるか設定されていない場合、これは値に展開されます。min
awk
$ID_minimum
1000
もしあなたなら本物必要に応じて、上記のループでコマンドを実行するのではなく、コマンドを印刷することができます。
getent passwd |
awk -F: -v min="${ID_minimum:-1000}" '$3 >= min && $1 != "nfsnobody" { print $1 }' |
while IFS= read -r user; do
printf 'xfs_quota -x -c "limit bsoft=5g bhard=6g %s" /home\n' "$user"
done
eval
生成されたコマンドを使用するか、別の方法で実行している場合、出力コマンド文字列に一重引用符ではなく二重引用符を使用すると、シェルは何らかの方法で混同されません。面倒な場合は、上記の最初のパラメータで一重引用符と二重引用符を変更してくださいprintf
。
答え2
for f in /etc/passwd;
実際には値が1つしかないループが存在しないため、これは少し愚かなことです。
しかし、問題はawkで一重引用符を印刷するようです。シェルからエスケープできますが、バックスラッシュエスケープを使用してawkとして印刷することもできます。数字\OOO
オブジェクト指向(存在する8進数)、やはり\047
そうです'
。だからここに1つの方法があります:
awk -F: -vID=$ID_minimum '$3>=1000 && $1!="nfsnobody" {
printf "xfs_quota -x -c \047limit bsoft=5g bhard=6g %s\047 /home\n", $1}' /etc/passwd
16進数でも同様のエスケープを使用できますが、次の文字が\x27
有効な16進数の場合、一部の実装では誤解を招く可能性があります。 (もちろん、ASCIIやUTF-8などのASCII互換文字セットを想定しています。)
答え3
awkのオプションを使用して-f -
stdinからスクリプトをインポートし、ここにドキュメントがあります。
awk -F: -v "ID=$ID_minimum" -f - <<'EOT' /etc/passwd
$3>=1000 && $1!="nfsnobody" {
print "xfs_quota -x -c 'limit bsoft=5g bhard=6g "$1"' /home "
}
EOT
答え4
怖い障害物ですが、速くて簡単です。
awk -F: -vQ="'" -vID=$ID_minimum '$3>=1000 && $1!="nfsnobody" { print "xfs_quota -x -c " Q "limit bsoft=5g bhard=6g $1" Q " /home "}' $f;