ZCT*_*ZCT 8 shell scripting bash
一段时间以来,我一直试图找到这个问题的答案。我正在编写一个快速脚本来运行基于 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
Run Code Online (Sandbox Code Playgroud)
问题是-c参数采用单引号中的命令,我无法弄清楚如何正确转义它,而且它$1也不会扩展到用户名中。
基本上我只是想让它输出:
xfs_quota -x -c 'limit bsoft=5g bhard=6g userone' /home
xfs_quota -x -c 'limit bsoft=5g bhard=6g usertwo' /home
Run Code Online (Sandbox Code Playgroud)
等等...
Kus*_*nda 13
要xfs_quota -x -c 'limit bsoft=5g bhard=6g USER' /home为每个USERUID 至少为的命令运行该命令$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
Run Code Online (Sandbox Code Playgroud)
请注意,在.之后的参数周围实际上不需要单引号-c。在这里我使用双引号是因为我希望 shell 扩展$user包含由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
Run Code Online (Sandbox Code Playgroud)
再次注意,如果您要使用eval或通过其他方式执行生成的命令,则在输出的命令字符串中使用双引号(而不是单引号)不会以任何方式混淆 shell 。如果它困扰你,只需在printf上面的第一个参数中交换单引号和双引号。
for f in /etc/passwd;
Run Code Online (Sandbox Code Playgroud)
这有点愚蠢,因为实际上没有只有一个值的循环。
但问题似乎是从 awk 打印单引号。您可以在 shell 中对它们进行转义,但也可以在 awk 中使用反斜杠转义来打印它们。是数值为OOO的字符(八进制),所以是。所以这将是一种方法:\OOO\047'
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
Run Code Online (Sandbox Code Playgroud)
您可以在 hex, 中使用类似的转义\x27符,但如果以下字符是有效的十六进制数字,则在某些实现中可能会被误解。(当然,我假设 ASCII 或兼容 ASCII 的字符集,例如 UTF-8。)
使用-f -awk 选项从 stdin 和 here-document 中获取脚本:
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
Run Code Online (Sandbox Code Playgroud)
这做到了。
awk -F: -vID=$ID_minimum '$3>=1000 && $1!="nfsnobody" { print "xfs_quota -x -c '"'"'limit bsoft=5g bhard=6g ''"$1"'''"'"' /home "}' /etc/passwd
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1361 次 |
| 最近记录: |