나는 한동안 이 질문에 대한 답을 찾으려고 노력해 왔습니다. 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;
실제로 값이 하나만 있는 루프가 존재하지 않기 때문에 이것은 약간 어리석은 일입니다.
하지만 문제는 awk에서 작은따옴표를 인쇄하는 것 같습니다. 셸에서 이스케이프할 수 있지만 백슬래시 이스케이프를 사용하여 awk로 인쇄할 수도 있습니다. 숫자 문자입니다\OOO
객체지향(존재하다8진수), 역시 \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
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;