파일에서 문자열을 읽고 두 번째 파일의 각 줄과 비교하는 방법

파일에서 문자열을 읽고 두 번째 파일의 각 줄과 비교하는 방법

저는 강화 부분을 포함할 OS 설치 후 스크립트를 작성 중입니다. 이 강화 섹션에서는 파일 A에서 커널 매개변수를 읽고 이를 /etc/sysctl.conf 파일과 비교합니다. 매개변수가 sysctl.conf에서 사용할 수 없으면 이를 sysctl.conf에 추가합니다.

사용자 정의 파일의 매개변수

################## Hardening ############################

kernel.exec-shield = 1
kernel.randomize_va_space = 1
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.default.log_martians = 1
net.ipv4.tcp_timestamps = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0

##########################################################

이제 보강을 위해 다음 줄을 추가했습니다.

for i in $(cat /etc/sysctl.conf)
do
        if ! grep -Fxq " $i " /etc/sysctl.conf
        then
        echo -e "$i" > ~/testfile
        fi
done

이 스크립트의 문제점은 커널 매개변수의 모든 공백을 공백의 한 줄로 처리하고 "for i in $(cat /etc/sysctl.conf)"의 시작 부분에서 문제가 시작된다는 것입니다.

디버깅 정보입니다

./LinuxHardening.sh
++ date
+ LOGDATE='Mon Feb  9 07:58:07 EST 2015'
+ echo Mon Feb 9 07:58:07 EST 2015
+ tee HardeningLog
Mon Feb 9 07:58:07 EST 2015
+ echo -e '\n############ Kernel Hardening ############'
+ tee -a HardeningLog

############ Kernel Hardening ############
++ cat kernelparms
+ for i in '$(cat kernelparms)'
+ grep -Fxq '##################' /etc/sysctl.conf
+ echo -e '##################'
+ for i in '$(cat kernelparms)'
+ grep -Fxq Hardening /etc/sysctl.conf
+ echo -e Hardening
+ for i in '$(cat kernelparms)'
+ grep -Fxq '############################' /etc/sysctl.conf
+ echo -e '############################'
+ for i in '$(cat kernelparms)'
+ grep -Fxq kernel.exec-shield /etc/sysctl.conf
+ echo -e kernel.exec-shield
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 1 /etc/sysctl.conf
+ echo -e 1
+ for i in '$(cat kernelparms)'
+ grep -Fxq kernel.randomize_va_space /etc/sysctl.conf
+ echo -e kernel.randomize_va_space
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 1 /etc/sysctl.conf
+ echo -e 1
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv4.icmp_echo_ignore_broadcasts /etc/sysctl.conf
+ echo -e net.ipv4.icmp_echo_ignore_broadcasts
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 1 /etc/sysctl.conf
+ echo -e 1
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv4.icmp_ignore_bogus_error_responses /etc/sysctl.conf
+ echo -e net.ipv4.icmp_ignore_bogus_error_responses
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 1 /etc/sysctl.conf
+ echo -e 1
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv4.tcp_syncookies /etc/sysctl.conf
+ echo -e net.ipv4.tcp_syncookies
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 1 /etc/sysctl.conf
+ echo -e 1
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv4.conf.all.log_martians /etc/sysctl.conf
+ echo -e net.ipv4.conf.all.log_martians
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 1 /etc/sysctl.conf
+ echo -e 1
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv4.conf.all.accept_redirects /etc/sysctl.conf
+ echo -e net.ipv4.conf.all.accept_redirects
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 0 /etc/sysctl.conf
+ echo -e 0
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv4.conf.all.rp_filter /etc/sysctl.conf
+ echo -e net.ipv4.conf.all.rp_filter
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 1 /etc/sysctl.conf
+ echo -e 1
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv4.conf.all.send_redirects /etc/sysctl.conf
+ echo -e net.ipv4.conf.all.send_redirects
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 0 /etc/sysctl.conf
+ echo -e 0
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv4.conf.default.accept_redirects /etc/sysctl.conf
+ echo -e net.ipv4.conf.default.accept_redirects
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 0 /etc/sysctl.conf
+ echo -e 0
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv4.conf.default.log_martians /etc/sysctl.conf
+ echo -e net.ipv4.conf.default.log_martians
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 1 /etc/sysctl.conf
+ echo -e 1
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv4.tcp_timestamps /etc/sysctl.conf
+ echo -e net.ipv4.tcp_timestamps
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 0 /etc/sysctl.conf
+ echo -e 0
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv6.conf.all.accept_redirects /etc/sysctl.conf
+ echo -e net.ipv6.conf.all.accept_redirects
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 0 /etc/sysctl.conf
+ echo -e 0
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv6.conf.default.accept_redirects /etc/sysctl.conf
+ echo -e net.ipv6.conf.default.accept_redirects
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 0 /etc/sysctl.conf
+ echo -e 0
+ for i in '$(cat kernelparms)'
+ grep -Fxq '##########################################################' /etc/sysctl.conf
+ echo -e '##########################################################'

답변1

한 줄씩 읽으려면 while을 사용하지 마세요.

while read -r line
do
        if ! grep -Fxq " $line " /etc/sysctl.conf
        then
        echo -e "$line" >> ~/testfile
        fi
done </etc/sysctl.conf

>를 >>로 바꾸세요.

답변2

다음과 같이 시도해 보세요:

while read i
do
        if ! grep -Fxq " $i " /etc/sysctl.conf
        then
        echo -e "$i" >> ~/testfile
        fi
done<kernelparms

답변3

awk관련된정렬:

awk '!/^($|#)/{arr[$1]=$0}END{for(param in arr) print arr[param]}' /etc/sysctl.conf custom.conf

순서가 중요한 경우:

awk '!/^($|#)/{
  arr[$1] = $0
}
END {
  for(key in arr)
    print arr[key]
}' /etc/sysctl.conf custom.conf | sort > hardened.conf

!/^($|#)/- 주석 줄이나 빈 줄을 무시합니다
{arr[$1]=$0}. - 각 줄을 arr에 저장하고 이를 커널 인수와 연결합니다. custom.conf동일한 인수가 나타날 때마다(즉, 읽을 마지막 파일에서) 줄이 업데이트됩니다.
END{for(param in arr) print arr[param]}- 모든 입력을 읽은 후 인쇄합니다. 각 커널 매개변수에 대한 관련 행.

답변4

이를 설정하면 IFS=$'\n'공백이 새 줄로 처리되지 않습니다.

관련 정보