따옴표가 있는 Bash awk 명령

따옴표가 있는 Bash awk 명령

나는 한동안 이 질문에 대한 답을 찾으려고 노력해 왔습니다. 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. 여기서는 $userextract 값이 포함된 변수를 쉘이 확장하기를 원하기 때문에 큰따옴표를 사용하고 있습니다 awk.

명령어에서 변수에 ${ID_minimum:-1000}값을 할당할 때 사용합니다 . 변수가 비어 있거나 설정되지 않은 경우 이는 값으로 확장됩니다.minawk$ID_minimum1000


만약 너라면진짜원하는 경우 위 루프에서 명령을 실행하는 대신 명령을 인쇄하도록 할 수 있습니다.

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;       

관련 정보