목차
Summary
안녕하세요,
리눅스에서 사용되는 라우팅 파일에 원하는 라우팅 정보를 쉽게 추가할 수 있는 Bash 스크립트를 소개하려고 합니다.
해당 스크립트를 사용하면 라우팅 테이블 정보를 효과적으로 관리하고, 실수 없이 추가 및 수정할 수 있습니다.
각 코드의 섹션별로 어떤 기능을 하는지 설명해 드리겠습니다.
1) 스크립트 개요
이 스크립트는 다음과 같은 기능을 제공합니다.
- 라우팅 파일의 위치 및 이름을 자동으로 파악
- IP 주소, 넷마스크, 게이트웨이의 유효성 검사
- 라우팅 정보의 순서를 지정하거나 자동으로 추가
- 중복된 라우팅 정보의 확인 및 경고
스크립트는 아래와 같은 주요 기능을 포함합니다.
- 유효성 검사:
스크립트는 입력된 IP 주소, 넷마스크, 게이트웨이의 유효성을 검사하여, 잘못된 정보가 입력되지 않도록 합니다. - 라우팅 정보 순서 지정:
사용자는 추가할 라우팅 정보의 순서를 직접 지정할 수 있습니다.
순서를 지정하지 않을 경우, 자동으로 마지막 순서에 추가합니다. - 중복 검사:
이미 존재하는 라우팅 정보가 입력될 경우 추가되지 않습니다.
스크립트는 해당 정보를 경고하고 중복된 정보를 출력합니다. - 라우팅 정보 추가:
사용자의 확인을 받은 후, 스크립트는 라우팅 파일에 새로운 라우팅 정보를 추가합니다.
2) 전체 코드 및 사용법
코드 펼처보기 ↓
#!/bin/bash
usage() {
echo " Error: No input value provided."
echo " Usage: $0 <Device_Name>"
echo " Ex: $0 bond0"
exit 1
}
if [ -z "$1" ]; then
usage
fi
ROUTE_PATH="/etc/sysconfig/network-scripts"
INTERFACE_NAME="$1"
ROUTE_FILE="route-$INTERFACE_NAME"
ROUTING_FILE="$ROUTE_PATH/$ROUTE_FILE"
if [ ! -e "$ROUTING_FILE" ]; then
echo "Error: $ROUTING_FILE not found."
exit 1
fi
validate_ip_address() {
local ip_address="$1"
local regex="^(25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9])){3}$"
if [[ $ip_address =~ $regex ]]; then
return 0
else
return 1
fi
}
get_add_info() {
last_seq_num=$(grep -oP "^ADDRESS\K[0-9]+" "$ROUTING_FILE" | sort -rn | head -n1)
echo "Current Last Sequence is [$last_seq_num]"
while true; do
read -p "NEW SEQUENCE NUMBER (Leave empty for adding to the end): " SEQ_NUM
if [[ $SEQ_NUM -gt $((last_seq_num + 1)) ]]; then
echo -e "\nEnter Less than $((last_seq_num + 1)) "
elif [[ -z "$SEQ_NUM" ]]; then
last_seq_num=$((last_seq_num + 1))
break
elif [[ "$SEQ_NUM" =~ ^[0-9]+$ ]]; then
last_seq_num=""
break
else
echo "Please enter a valid number or leave it empty."
fi
done
while true; do
read -p "NEW ADDRESS : " NEW_ADDRESS
if validate_ip_address "$NEW_ADDRESS"; then
break
else
echo "Please enter a valid IP address (0.0.0.0 ~ 255.255.255.255)."
fi
done
while true; do
read -p "NEW NETMASK : " NEW_NETMASK
if validate_ip_address "$NEW_NETMASK"; then
break
else
echo "Please enter a valid IP address (0.0.0.0 ~ 255.255.255.255)."
fi
done
while true; do
read -p "NEW GATEWAY : " NEW_GATEWAY
if validate_ip_address "$NEW_GATEWAY"; then
break
else
echo "Please enter a valid IP address (0.0.0.0 ~ 255.255.255.255)."
fi
done
echo "========================="
if [[ -z $last_seq_num ]]; then
echo -e "ADDRESS$SEQ_NUM = $NEW_ADDRESS \nNETMASK$SEQ_NUM = $NEW_NETMASK \nGATEWAY$SEQ_NUM = $NEW_GATEWAY"
else
echo -e "ADDRESS$last_seq_num = $NEW_ADDRESS \nNETMASK$last_seq_num = $NEW_NETMASK \nGATEWAY$last_seq_num = $NEW_GATEWAY"
fi
echo "========================="
read -p "Are you going to add this? [y/n]: " confirm
while true; do
case $confirm in
"y")
echo ""
break
;;
"n")
echo -e "\nCancel the add.\n"
exit 1
;;
*)
read -p "Please enter 'y' or 'n' [y/n]: " confirm
;;
esac
done
}
add_new_route() {
if grep -qw "$NEW_ADDRESS" $ROUTING_FILE; then
echo "[$NEW_ADDRESS] is already exists in $ROUTING_FILE"
tmp=$(grep $NEW_ADDRESS $ROUTING_FILE | awk -F= '{print $1}')
tmp_seq=${tmp#ADDRESS} # Extract sequence number with more than one digit
echo "`cat $ROUTING_FILE | egrep -w "ADDRESS$tmp_seq|NETMASK$tmp_seq|GATEWAY$tmp_seq"`"
exit 1
fi
cp $ROUTING_FILE $ROUTING_FILE.bk
local TEMP_FILE=$(mktemp)
if [[ -z "$SEQ_NUM" ]]; then
SEQ_NUM=$(grep -oP "^ADDRESS\K[0-9]+" "$ROUTING_FILE" | sort -rn | head -n1)
((SEQ_NUM++))
echo "" >> "$ROUTING_FILE"
echo "ADDRESS$SEQ_NUM=$NEW_ADDRESS" >> "$ROUTING_FILE"
echo "NETMASK$SEQ_NUM=$NEW_NETMASK" >> "$ROUTING_FILE"
echo "GATEWAY$SEQ_NUM=$NEW_GATEWAY" >> "$ROUTING_FILE"
if [ $? -eq 0 ]; then
echo "ROUTE ADD SUCCESS."
else
echo "ADDRESS$SEQ_NUM=$NEW_ADDRESS"
echo "NETMASK$SEQ_NUM=$NEW_NETMASK"
echo "GATEWAY$SEQ_NUM=$NEW_GATEWAY"
echo "Invalid Error"
fi
else
# Rearrange sequence numbers
awk -v seq=$SEQ_NUM -v addr=$NEW_ADDRESS -v mask=$NEW_NETMASK -v gw=$NEW_GATEWAY 'BEGIN {FS=OFS="="; inserted=0}
/^ADDRESS[0-9]+/ {
split($1, a, "ADDRESS");
num = a[2] + 0; # Convert to number
if (num == seq && !inserted) {
print "ADDRESS" seq "=" addr;
print "NETMASK" seq "=" mask;
print "GATEWAY" seq "=" gw;
print "";
inserted=1;
num++;
} else if (num >= seq) {
num++;
}
print "ADDRESS" num "=" $2;
next;
}
/^NETMASK[0-9]+/ {
split($1, a, "NETMASK");
num = a[2] + 0; # Convert to number
if (num >= seq) {
num++;
}
print "NETMASK" num "=" $2;
next;
}
/^GATEWAY[0-9]+/ {
split($1, a, "GATEWAY");
num = a[2] + 0; # Convert to number
if (num >= seq) {
num++;
}
print "GATEWAY" num "=" $2;
next;
}
{print $0}
' $ROUTING_FILE > $TEMP_FILE
mv $TEMP_FILE $ROUTING_FILE
if [ $? -eq 0 ]; then
echo "ROUTE ADD SUCCESS."
else
echo "ADDRESS$SEQ_NUM=$NEW_ADDRESS"
echo "NETMASK$SEQ_NUM=$NEW_NETMASK"
echo "GATEWAY$SEQ_NUM=$NEW_GATEWAY"
echo "Invalid Error"
fi
fi
}
get_add_info
add_new_route
exit 0
사용법 펼처보기 ↓
./script_name.sh <Device_Name>
또는
sh script_name.sh <Device_Name>
예시:
# ./script_name.sh bond0
Current Last Sequence is [3]
NEW SEQUENCE NUMBER (Leave empty for adding to the end):
NEW ADDRESS : 50.50.50.0
NEW NETMASK : 255.255.255.0
NEW GATEWAY : 192.168.227.1
=========================
ADDRESS4 = 50.50.50.0
NETMASK4 = 255.255.255.0
GATEWAY4 = 192.168.227.1
=========================
Are you going to add this? [y/n]: y
ROUTE ADD SUCCESS.
수정전 | 수정후 |
# cat route-bond0 #des1 ADDRESS0=10.10.10.128 NETMASK0=255.255.255.128 GATEWAY0=192.168.227.1 ADDRESS1=20.20.20.64 NETMASK1=255.255.255.192 GATEWAY1=192.168.227.1 ADDRESS2=30.30.30.32 NETMASK2=255.255.255.224 GATEWAY2=192.168.227.1 ADDRESS3=40.40.40.16 NETMASK3=255.255.255.240 GATEWAY3=192.168.227.1 |
# cat route-bond0 #des1 ADDRESS0=10.10.10.128 NETMASK0=255.255.255.128 GATEWAY0=192.168.227.1 ADDRESS1=20.20.20.64 NETMASK1=255.255.255.192 GATEWAY1=192.168.227.1 ADDRESS2=30.30.30.32 NETMASK2=255.255.255.224 GATEWAY2=192.168.227.1 ADDRESS3=40.40.40.16 NETMASK3=255.255.255.240 GATEWAY3=192.168.227.1 ADDRESS4=50.50.50.0 NETMASK4=255.255.255.0 GATEWAY4=192.168.227.1 |
여기서부터는 스크립트의 내용을 각 섹션별로 나누어 설명하고자 합니다.
만약 사용만 하시려면 위 사용법만 살펴보셔도 무방합니다.
코드를 좀 더 자세히 이해하고 입맛대로 수정하실 분들을 위해 자세히 설명드릴테니,
혹여나 잘못된 부분이 있다면 댓글 부탁드려용..ㅎㅎ
3) 코드설명
1. 스크립트 실행 확인
- 이 부분은 사용자가 스크립트를 실행할 때 필요한 인자 (Device_Name)를 제공했는지 확인
- 제공되지 않았다면, usage 함수를 호출하여 사용법을 출력하고 스크립트를 종료
usage() {
echo " Error: No input value provided."
echo " Usage: $0 <Device_Name>"
echo " Ex: $0 bond0"
exit 1
}
if [ -z "$1" ]; then
usage
fi
2. 라우팅 파일 경로 지정
- 여기서는 라우팅 파일의 기본 경로와 인터페이스 이름을 설정
- 사용자가 입력한 인터페이스 이름을 바탕으로 라우팅 파일의 전체 경로를 구성
ROUTE_PATH="/etc/sysconfig/network-scripts"
INTERFACE_NAME="$1"
ROUTE_FILE="route-$INTERFACE_NAME"
ROUTING_FILE="$ROUTE_PATH/$ROUTE_FILE"
3. 입력한 정보의 유효성 검사 - validate_ip_address()
- 이 함수는 주어진 정보가 유효한 형식인지 확인
- 유효한 IP 주소 형식 (0.0.0.0 ~ 255.255.255.255)이 아닐 경우, 사용자에게 다시 입력을 요청
4. 새로운 라우팅 정보를 파일에 입력 - get_add_info()
- 라우팅 파일에서 현재까지 사용된 가장 큰 ADDRESS 시퀀스 번호를 탐색
last_seq_num=$(grep -oP "^ADDRESS\K[0-9]+" "$ROUTING_FILE" | sort -rn | head -n1)
- 사용자에게 새로운 시퀀스 번호를 입력받고, 입력하지 않으면 자동으로 (마지막 시퀀스+1) 번호를 할당
while true; do
read -p "NEW SEQUENCE NUMBER (Leave empty for adding to the end): " SEQ_NUM
if [[ $SEQ_NUM -gt $((last_seq_num + 1)) ]]; then
echo -e "\nEnter Less than $((last_seq_num + 1)) "
elif [[ -z "$SEQ_NUM" ]]; then
last_seq_num=$((last_seq_num + 1))
break
elif [[ "$SEQ_NUM" =~ ^[0-9]+$ ]]; then
last_seq_num=""
break
else
echo "Please enter a valid number or leave it empty."
fi
done
- 추가할 IP주소, NETMASK, 게이트웨이 정보를 입력받고, 유효한 주소 형식인지 판단
while true; do
read -p "NEW ADDRESS : " NEW_ADDRESS
if validate_ip_address "$NEW_ADDRESS"; then
break
else
echo "Please enter a valid IP address (0.0.0.0 ~ 255.255.255.255)."
fi
done
while true; do
read -p "NEW NETMASK : " NEW_NETMASK
if validate_ip_address "$NEW_NETMASK"; then
break
else
echo "Please enter a valid IP address (0.0.0.0 ~ 255.255.255.255)."
fi
done
while true; do
read -p "NEW GATEWAY : " NEW_GATEWAY
if validate_ip_address "$NEW_GATEWAY"; then
break
else
echo "Please enter a valid IP address (0.0.0.0 ~ 255.255.255.255)."
fi
done
- 입력한 정보를 다시 한번 출력하여 확인시키고 해당 정보를 추가할 것인지 확인
echo "========================="
if [[ -z $last_seq_num ]]; then
echo -e "ADDRESS$SEQ_NUM = $NEW_ADDRESS \nNETMASK$SEQ_NUM = $NEW_NETMASK \nGATEWAY$SEQ_NUM = $NEW_GATEWAY"
else
echo -e "ADDRESS$last_seq_num = $NEW_ADDRESS \nNETMASK$last_seq_num = $NEW_NETMASK \nGATEWAY$last_seq_num = $NEW_GATEWAY"
fi
echo "========================="
read -p "Are you going to add this? [y/n]: " confirm
while true; do
case $confirm in
"y")
echo ""
break
;;
"n")
echo -e "\nCancel the add.\n"
exit 1
;;
*)
read -p "Please enter 'y' or 'n' [y/n]: " confirm
;;
esac
done
요약하면 `get_add_info()` 함수는 사용자로부터 새로운 라우팅 정보를 입력받고,
해당 정보의 유효성을 검사한 후, 사용자의 최종 확인을 받아 정보를 추가할지 취소할지 결정합니다.
5. 입력받은 정보를 실제로 파일에 추가 - add_new_route()
- 라우팅 파일에서 새로운 IP주소(`$NEW_ADDRESS`) 가 이미 존재하는지 확인
- 만약 존재한다면, 중복된 정보를 출력하고 스크립트 종료
if grep -qw "$NEW_ADDRESS" $ROUTING_FILE; then
echo "[$NEW_ADDRESS] is already exists in $ROUTING_FILE"
tmp=$(grep $NEW_ADDRESS $ROUTING_FILE | awk -F= '{print $1}')
tmp_seq=${tmp#ADDRESS} # Extract sequence number with more than one digit
echo "`cat $ROUTING_FILE | egrep -w "ADDRESS$tmp_seq|NETMASK$tmp_seq|GATEWAY$tmp_seq"`"
exit 1
fi
- 현재 라우팅 파일을 백업하여 수정되기 전 파일을 보존
cp -f $ROUTING_FILE $ROUTING_FILE.bk
- 추가할 라우팅 정보의 순서가 기본값(미입력)인 경우 파일 제일 하단에 추가
if [[ -z "$SEQ_NUM" ]]; then
SEQ_NUM=$(grep -oP "^ADDRESS\K[0-9]+" "$ROUTING_FILE" | sort -rn | head -n1)
((SEQ_NUM++))
echo "" >> "$ROUTING_FILE"
echo "ADDRESS$SEQ_NUM=$NEW_ADDRESS" >> "$ROUTING_FILE"
echo "NETMASK$SEQ_NUM=$NEW_NETMASK" >> "$ROUTING_FILE"
echo "GATEWAY$SEQ_NUM=$NEW_GATEWAY" >> "$ROUTING_FILE"
if [ $? -eq 0 ]; then
echo "ROUTE ADD SUCCESS."
else
echo "ADDRESS$SEQ_NUM=$NEW_ADDRESS"
echo "NETMASK$SEQ_NUM=$NEW_NETMASK"
echo "GATEWAY$SEQ_NUM=$NEW_GATEWAY"
echo "Invalid Error"
fi
`$SEQ_NUM` 변수가 지정되지 않은 경우 라우팅 파일의 마지막에 새로운 정보를 추가합니다.
- 순서를 지정한경우 해당 위치에 새로운 정보를 입력하고 라우팅 파일의 시퀀스 번호를 재정의
else
# Rearrange sequence numbers
awk -v seq=$SEQ_NUM -v addr=$NEW_ADDRESS -v mask=$NEW_NETMASK -v gw=$NEW_GATEWAY 'BEGIN {FS=OFS="="; inserted=0}
/^ADDRESS[0-9]+/ {
split($1, a, "ADDRESS");
num = a[2] + 0; # Convert to number
if (num == seq && !inserted) {
print "ADDRESS" seq "=" addr;
print "NETMASK" seq "=" mask;
print "GATEWAY" seq "=" gw;
print "";
inserted=1;
num++;
} else if (num >= seq) {
num++;
}
print "ADDRESS" num "=" $2;
next;
}
/^NETMASK[0-9]+/ {
split($1, a, "NETMASK");
num = a[2] + 0; # Convert to number
if (num >= seq) {
num++;
}
print "NETMASK" num "=" $2;
next;
}
/^GATEWAY[0-9]+/ {
split($1, a, "GATEWAY");
num = a[2] + 0; # Convert to number
if (num >= seq) {
num++;
}
print "GATEWAY" num "=" $2;
next;
}
{print $0}
' $ROUTING_FILE > $TEMP_FILE
mv $TEMP_FILE $ROUTING_FILE
if [ $? -eq 0 ]; then
echo "ROUTE ADD SUCCESS."
else
echo "ADDRESS$SEQ_NUM=$NEW_ADDRESS"
echo "NETMASK$SEQ_NUM=$NEW_NETMASK"
echo "GATEWAY$SEQ_NUM=$NEW_GATEWAY"
echo "Invalid Error"
fi
fi
사용자가 원하는 위치에 정보를 추가하고 awk 명령을 통해 시퀀스 번호를 1씩 증가시켜 재정의 합니다.
이후 `$TEMP_FILE` 에 저장해 두었던 내용을 엎어치면서 성공/실패 메시지를 출력합니다.
4) 마치며
오늘은 리눅스에서 라우팅 테이블 관리에 사용되는 라우팅 파일에 원하는 정보를 추가하는 스크립트를 살펴보았습니다.
이 스크립트를 사용하면, 리눅스의 라우팅 정보를 효과적으로 관리하고 추가할 수 있습니다.
특히, 복잡한 네트워크 환경에서 라우팅 정보를 자주 변경해야 하는 경우, 이 스크립트는 큰 도움이 될 것입니다.
'Shell Script > Routing Check' 카테고리의 다른 글
(Bash) 리눅스 라우팅 파일 검증 스크립트 (0) | 2023.09.15 |
---|---|
(Shell Script) 리눅스 Routing 파일 내용(순서) 확인 script (0) | 2023.04.13 |