![3개 파일의 bash 스크립트 입력](https://linux55.com/image/166329/3%EA%B0%9C%20%ED%8C%8C%EC%9D%BC%EC%9D%98%20bash%20%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%20%EC%9E%85%EB%A0%A5.png)
원시 데이터로 이 3개의 파일을 만듭니다.
quota username bytes
20480000 [email protected] 896
30720000 [email protected] 3002766
20480000 [email protected] 20472940
20480000 [email protected] 2351
Here I want that if bytes if any user is equal or greater than to quota then the username should be printed or I'll perform another task to block the user.
다음과 같은 3개의 파일이 있습니다.
users.txt
Output:
[email protected]
[email protected]
consumed_quota.txt
Output:
20
5
allowed_quota.txt
Output:
20
10
[email protected]
파일의 사용자가 . users.txt
consumed_quota
보다 크거나 같으면 사용자를 인쇄하고 싶습니다 allowed_quota
.
배쉬 프로그램이란 무엇입니까?
도와주세요.
아래 코드를 시도 중이지만 일치하는 사용자 대신 모든 사용자가 인쇄됩니다.
#!/bin/bash
mysql -e 'select postfix.m.quota, q.* from postfix.mailbox m, postfix.quota2 q where m.username = q.username' > /tmp/all_users_query
username=`cat /tmp/all_users_query | cut -f2 | grep -v username > /tmp/usernf`
quota=`cat /tmp/all_users_query | cut -f1 | grep -v quota > /tmp/quotaf`
consumed=`cat /tmp/all_users_query | cut -f3 | grep -v bytes > /tmp/consumedf`
function show_users()
{
username=`cat /tmp/usernf`
for i in $username
do
echo $i
done
}
function actual_quota()
{
quota=`cat /tmp/quotaf`
for i in $quota
do
akb=`echo $i/1000 | bc`
amb=`echo $akb/1000 | bc`
echo $amb
done
}
function used_quota()
{
consumed=`cat /tmp/consumedf`
for i in $consumed
do
ukb=`echo "$i/1000" | bc`
umb=`echo "$ukb/1000" | bc`
echo "$umb"
done
}
declare -a arr_users="$(show_users)"
declare -a arr_act_quota="$(actual_quota)"
declare -a arr_use_quota="$(used_quota)"
for u in ${arr_users[@]}
do
for i in ${arr_use_quota[@]}
do
# echo $i;
for j in ${arr_act_quota[@]}
do
if [ "$j" == "$i" ]
then
echo $u;
break;
fi
done
done
done
답변1
스크립트를 직접 만들었고 예상한 결과를 얻었습니다.
#!/bin/bash
rm -rf /tmp/over_quota_users
mysql -e 'select postfix.m.quota, q.* from postfix.mailbox m, postfix.quota2 q where m.username = q.username and q.bytes >= m.quota-bytes;' | cut -f2 | grep -v username > /tmp/over_quota_users
#Function to get users;
function show_users()
{
username=`cat /tmp/over_quota_users`
for i in $username
do
echo $i
done
}
#Function to get active users;
function check_active()
{
for i in $(show_users); do
mysql -e 'select username, active from postfix.mailbox where username = "'$i'" and active = 1;' | grep -v username
done
result=`echo $?`
echo $result
}
active_results=$(check_active $(show_users))
if [ "$active_results" == 1 ];
then
exit 0;
else
for j in $(show_users); do
#changing over quota users to inactive.
mysql -e 'update postfix.mailbox set active = '0' where username = "'$j'"';
done
rm -rf /tmp/oqa_ul_2_admin.txt
echo "" > /tmp/oqa_ul_2_admin.txt
echo "These users were over quota and active " >> /tmp/oqa_ul_2_admin.txt
echo "" >> /tmp/oqa_ul_2_admin.txt
echo "---------------------------------------" >> /tmp/oqa_ul_2_admin.txt
echo "$(show_users)" >> /tmp/oqa_ul_2_admin.txt
echo "" >> /tmp/oqa_ul_2_admin.txt
echo "---------------------------------------" >> /tmp/oqa_ul_2_admin.txt
echo "" >> /tmp/oqa_ul_2_admin.txt
/usr/bin/mail -s "Blocked Over quota and active users" [email protected] < /tmp/oqa_ul_2_admin.txt
fi
답변2
요청의 경우 데이터를 3개의 파일로 분할한 다음 파일을 읽어야 할 필요가 없습니다. 직접 읽어보실 수 있습니다/tmp/all_users_query
그렇지 않으면 @Kusalananda 답변은 상당히 적절하고 완벽하게 기능하는 답변입니다.
귀하가 설명하는 파일을 확인한 결과 해당 파일이 다음 순서로 쿼리에서 비롯된 것으로 확인되었습니다(상당히 명백함).
allowed_quota
users
consumed_quota
그래서 나는 다음을 생각해 냈습니다.::
#!/bin/bash
mysql -e 'select postfix.m.quota, q.* from postfix.mailbox m, postfix.quota2 q where m.username = q.username' > /tmp/all_users_query
gawk '{ if ($3 >= $1) { printf("\n%s ", $2); } }' /tmp/all_users_query
exit 0
또 다른 (더 나은) 해결책은 출력에 추가 필드를 추가하는 것입니다(다른 곳에서 출력 파일을 읽는 경우 삭제할 수 있음). overflow
사용자가 소비한 오버플로 바이트 수를 표시하는 추가 필드가 있습니다 . 즉 consumed_quota
, 와 의 단순한 차이입니다 allowed_quota
.
출력은 오버플로 필드를 기준으로 내림차순으로 정렬되어 가장 높은 소비량이 먼저 표시됩니다.
#!/bin/bash
mysql -e 'select postfix.m.quota, q.* from postfix.mailbox m, postfix.quota2 q where m.username = q.username' > /tmp/all_users_query
gawk '{ allowed_amount = $1; consumed_amount = $3; if (consumed_amount >= allowed_amount) { overflow = (consumed_amount - allowed_amount); printf("\n%s\t%d", $2, overflow); } }' all_users_query | sort --key=2gr
exit 0
답변3
이 행이 Output:
실제로 데이터의 일부가 아니라고 가정하면,
$ paste users.txt consumed_quota.txt allowed_quota.txt | awk -F '\t' '$2 >= $3 { print $1 }'
[email protected]
이 paste
명령은 열 1이 사용자 이름, 열 2가 사용된 할당량, 열 3이 허용된 할당량인 탭으로 구분된 데이터 세트를 생성합니다.
awk
사용된 할당량이 허용된 할당량보다 크거나 같은 경우 프로그램은 탭으로 구분된 데이터를 읽고 사용자 이름을 인쇄합니다.
또는 할당량을 초과하는 사용자 이름을 데이터베이스에 직접 쿼리하세요.
mysql -e '
SELECT q.username
FROM postfix.quota2 q
WHERE q.bytes > q.quota'