뭘 이런걸..

Posted
Filed under Tech/프로그래밍
정말 오랜만에 blog 에 posting 을 해 봅니다 :)

bash 에서 옵션 처리를 할 경우, bash 의 내장 함수인 getopts 또는 GNU getopt 를 사용하게 되는데, 필자의 경우에는 long option 을 제공하는 GNU getopt 를 더 선호하는 편입니다.

하지만 GNU getopt 를 사용할 경우 치명적인 문제가 하나 있는데, 바로 옵션 값에 공백 문자가 있을 경우, getopt -> set 을 하는 과정에서 옵션 값의 공백문자를 기준으로 분리가 되어 버리는 문제 입니다. (set 을 하는 이유는, 옵션과 인자값 순서를 섞어도 되게 하기 위해서 입니다.) 예를 들어

#!/bin/bash

opts="$( getopt -o h -u -l help -- $@ )"
set -- ${opts}
echo "$@"
echo "$3"
와 같이 코드를 만들고, 실행을 하면 다음과 같이 출력이 됩니다.
[user@host ~]$ bash test.sh -h "1 2 3"
-h -- 1 2 3
1
출력되는 $3 은 기대하는 "1 2 3" 이 아니라 "1" 이 됩니다.

그래서 이 문제는 해결하기 위해서는 다음과 같이 해 볼 수 있습니다.

#!/bin/bash

for i
do
[[ $i =~ [[:space:]] ]] && opt[n++]="\"${i}\"" || opt[n++]="${i}"
done
echo "input: ${opt[@]}"

opts="$( eval getopt -o ah: -l aa,hhh: -- ${opt[@]} )"
echo "opts -> ${opts}"
eval set -- ${opts}
for i
do
case "${i}" in
-a|--aa)
A=1
shift
;;
-h|--hhh)
H="${2}"
shift 2
;;
--)
shift;
break
esac
done

echo "$@"
echo "----"
echo "-h -> $H"
echo "\$1 -> $1"
echo "\$2 -> $2"
echo "\$3 -> $3"
echo "\$4 -> $4"
결과는
[user@host ~]$ bash test.sh "123 456" -h '\"abc def\"' 789
input: -h "\"abc def\"" "123 456" 789
opts -> -h '"abc def"' -- '123 456' '789'
123 456 789
----
-h -> "abc def"
$1 -> 123 456
$2 -> 789
$3 ->
$4 ->


--
코드를 조금 더 업데이트 해 보았습니다. 옵션값이 quote 를 사용할 떄 escape 를 해야 했는데 불편해서 하지 않아도 되도록 개선해 보았습니다. 이 이슈 때문에 getopt 를 eval 을 했었는데 굳이 하지 않아도 되었더군요. ㅠ

#!/bin/bash

echo "input: $@"

opts="$( getopt -o ah: -l aa,hhh: -- "$@" )"
echo "opts -> ${opts}"
eval set -- "${opts}"

echo "input -> ${opts}"

for i
do
case "${i}" in
-a|--aa)
A=1
shift
;;
-h|--hhh)
H="${2}"
shift 2
;;
--)
shift;
break
esac
done

echo "$@"
echo "----"
echo "-h -> $H"
echo "\$1 -> $1"
echo "\$2 -> $2"
echo "\$3 -> $3"
echo "\$4 -> $4"
이렇게 하면 옵션값에 quote  를 사용할 때 escape 를 하지 않아도 됩니다.
[user@host ~]$ bash test.sh 123\ 456 -h '"abc def"' 789
iinput: 123 456 -h "abc def" 789
opts -> -h '"abc def"' -- '123 456' '789'
input -> -h '"abc def"' -- '123 456' '789'
123 456 789
----
-h -> "abc def"
$1 -> 123 456
$2 -> 789
$3 ->
$4 ->
2023/01/06 13:22 2023/01/06 13:22
Posted
Filed under Tech/안녕리눅스
안녕 리눅스 업데이트 서버가 있는 IDC 의 전원 공사로 인하여 다음 기간 동안 홈페이지 운영및 yum repository 서버 운영이 중단 되어, yum update 가 이 기간 동안 불가능 하오니 업무에 참고 바랍니다.

서비스 중지 : 2021.01.22 17:00
서비스 재개 : 2022.01.25 언젠가..

서비스 재개는 IDC 사정에 따라 유동적일 수 있습니다.

긴급 업데이트나, yum 사용이 필요할 경우에는, /etc/yum.repos.d/Annyung.repo 설정 파일에서 mirrorolist 항목을 baseurl 로 변경하여 긴급 사용할 수 있습니다.

[AN:core]
baseurl=http://ftp.kr.freebsd.org/pub/AnNyung/$annyungver/core/$basearch

[AN:base]
baseurl=http://ftp.kr.freebsd.org/pub/AnNyung/$annyungver/base/$basearch

[AN:xless]
baseurl=http://ftp.kr.freebsd.org/pub/AnNyung/$annyungver/xless/$basearch

[AN:addon]
baseurl=http://ftp.kr.freebsd.org/pub/AnNyung/$annyungver/addon/$basearch
2021/01/19 23:39 2021/01/19 23:39
돌멩이

진짜.... 1년넘게 중지 되는거 아니지요???

김정균

ㅎㅎ 1년 쉬고 싶었나 봐요. 그럴 때도 되지 않았나

Posted
Filed under Tech/프로그래밍
디스크 크기나 네트워크 전송 대역폭 등을 단위대로 보기 좋게 하기 위한 코드를 살펴보겠습니다.
C나 여러 언어로 많이 있으나, bash 로는 딱히 마음에 드는 코드가 없어 만들어 보았습니다.

HUMANREADABLE_SIZE_SUFFIX=( "B" "KB" "MB" "GB" "TB" )
# HUMANREADABLE_SIZE req_size base_suffix
function HUMANREADABLE_SIZE {
local suffix=${2:-0}
local size=$1
local isize=${size}

while [ 1 ]
do
(( isize < 1024 )) && break
size="$( bc <<< "scale = 2; ${size} / 1024" )"
isize=${size%%.*}
let "suffix += 1"
done

echo "${size} ${HUMANREADABLE_SIZE_SUFFIX[suffix]}"
}


사용법은 간단합니다.

HUMANREADABLE_SIZE 입력_숫자 입력단위(0-B,1-KB,2-MB,3-GB)


[root@host ~]# # convert 1024 B
[root@host ~]# HUMANREADABLE_SIZE 1024
1KB
[root@host ~]# # convert 1024 KB
[root@host ~]# HUMANREADABLE_SIZE 1024 1
1MB
[root@host ~]# # convert 1024 MB
[root@host ~]# HUMANREADABLE_SIZE 1024 2
1GB
[root@host ~]# # convert 1024 GB
[root@host ~]# HUMANREADABLE_SIZE 1024 3
1TB


변환 값을 변수로 받고 싶다면 다음과 같이 할 수 있습니다.


[root@host ~]# SIZE=$( HUMANREADABLE_SIZE 1024 3 )
[root@host ~]# echo -n ${SIZE} # newline 이 없어야 할 경우..
2021/01/13 11:45 2021/01/13 11:45
Posted
Filed under Tech/안녕리눅스
안녕 리눅스 2 EOL (End Of Life) 공지 입니다.

안녕 리눅스 2의 모체인 CentOS 6 의 Life time 이 2020/11/30 종료가 되어, 안녕 리눅스 2도 같이 EOL 이 종료 됩니다.

다만, 현재 제가 아직 운영 중인 CentOS 6 이 남아 있는지라, 이 서버가 유지될 때 까지 잠시 동안은 critical bug fix 는 지원될 수도 있을 것 같습니다. 아마 2021년 상반기 안으로 정리가 되지 않을까 싶습니다.

현재, CentOS 6 이 mirror.centos.org 에서 제거 되고, valut.centos.org 로 이동이 되어, 안녕 리눅스 2에서 yum 이 동작하지 않습니다. 이 문제를 수정하기 위하여 다음의 명령을 수행해 주시면 됩니다.

[root@host ~]# rpm -Uhv http://mirror.oops.org/pub/AnNyung/2/core/x86_64/annyung-release-2.8-2.an2.noarch.rpm


P.S.
안녕 리눅스 3은 Oracle linux 또는 Rocky linux 기반으로 될 지도 모르겠습니다. Rocky linux 기반일 경우에는 많이 지연될 수 있을 것 같습니다. (아직 출시가 되지 않아서 --;) 아직은 약간 관망 중입니다.
2020/12/20 06:29 2020/12/20 06:29
Posted
Filed under Tech/안녕리눅스
안녕 리눅스  2 에서 독자 노선을 포기하고 clone 배포본 base 로 잡기 시작하면서, 버전의 괴리가 커지는 것 같아 안녕 리눅스 4는 출시하지 않고 버전을 맞추어 8 로 릴리즈 할 예정 입니다.

안녕 리눅스 3 작업 시에, systemd 에 대한 경험이 너무 없었고, RHEL 6에서 7로의 변화에서도 많은 부분을 놓쳐서 legacy 설정이나 init scritp 를 이용하고 있었는데, 안녕 8에서는 이런 부분을 좀 더 향상 시키기 위하여 RHEL 8 로 경험치를 좀 쌓고 있습니다. 그리고 RHEL 7에서 당한 것들을 보아 8.3 또는 8.4 를 base 로 안녕 8을 생각하고 있었으나, RHEL 6의 EOL 이 2020.11.30 로 다가오면서, 안녕 2의 EOL 역시 같이 종료를 되므로, 이 시점에 맞추어 8.2 또는 8.3 으로 release 를 해 보려고 합니다. 물론 CentOS 가 RHEL 보다 1~2달 정도 늦게 나오므로, 아마 실제 출시는 CentOS 8.3 에 맞춰지지 않을까 예상은 합니다만, 안녕 2의 EOL 때문에 일단은 2020.11.30 을 목표로 (아마 이 시점이면 8.2 base 가 될 수도 있을 겁니다.) 진행은 하고 있으며, 늦어지면 CentOS 8.3 출시에 맞춰서 진행될 것으로 보입니다.

출시 고지는 http://annyung.oops.org/?m=data&p=roadmap 의 [ 8 ] 섹션에 출시 날자가 업데이트 될 예정이니 참고 하시기 바랍니다.
2020/06/13 02:47 2020/06/13 02:47
김정균

출시일 약속은 못 지켰지만.. 내년 1/4 분기 이내로 출시는 가능할 것으로보고 있었는데, 어제자로 CentOS 에서 CentOS 8 release 에 대한 중단 공지를 올려 버렸네요. Release 는 더이상 배포하지 않고 Appstream 에만 집중하겠다는 발표인데, 안녕 리눅스 8이 Release 로 개발이 되어져서, Appstream 으로 변경을 해야 하나 고민 중입니다. 한 2-3주 정도는 흘러가는 형세를 관망해야 할 듯 싶네요. 일단은 현재 잠깐 작업은 멈춘 상태 입니다.

JellyPo

항상 고맙습니다. 안녕리눅스 설정을 보면 많은 공부가 됩니다.

Posted
Filed under Tech/프로그래밍
만들 때 마다 헷갈리고 까먹어서 기록해 놓아야 겠다.

# USAGE: compare_version OLD NEW
# RETURN:
# (OLD == NEW) return 0
# (OLD < NEW) return 1
# (OLD > NEW ) return 2
function compare_version {
local opt
[[ $1 == $2 ]] && return 0

# -V option 이 지원되지 않을 경우, 숫자 이외의 문자가 들어간 버전 비교가
# 정확하지 않을 수 있다. 예) 2.1.9-3el6_7.2
sort -V >& /dev/null <<< "aa"
[[ $? == 0 ]] && opt="V"

test "$(printf '%s\n' "$@" | sort -r${opt} | head -n 1)" != "$1";
res=$?
[[ $res == 0 ]] && return 1 || return 2
}


결과

[root@host ~]# source version_comapre.sh
[root@host ~]# compare_version 3 3
0
[root@host ~]# compare_version 3 4
1
[root@host ~]# compare_version 4 3
2
[root@host ~]#
2020/06/08 16:41 2020/06/08 16:41
Posted
Filed under Tech/프로그래밍
서버를 관리하다 보면 legacy OS 까지 고려하면서 코드를 작성해야 할 경우가 종종 있습니다.

스크립팅을 하다 보면 sort -V 옵션을 종종 사용해야 할 경우가 있습니다. 그런데 old OS 에 있는 sort 는 -V 옵션이 없는 경우가 있을 수 있습니다.

[root@host ~]# sort --help | grep -- "-V"
-V, --version-sort natural sort of (version) numbers within text
[root@host ~]#

sort -V 옵션이 필요한 경우는 대부분 다음과 같습니다.

cat << EOL | sort
1
2
10
20
EOL

위의 코드의 결과로는 보통은 1.. 2.. 10 .. 20 의 순서대로 나오기를 기대하게 됩니다. 하지만 위의 코드 결과는 실제

1
10
2
20

과 같이 의도하지 않는 출력이 되게 됩니다. 그러다 보니 어쩔수 없이 sort -V 를 구현을 해야 하게 됩니다.

아래 코드는 sort -V 옵션을 bash function 으로 만든 것입니다. license 는 BSD 2 clause 로 사용해 주시면 됩니다.

function sortv {
local var
local i

if [[ $# == 0 ]]; then
i=0
while read var_t
do
var[i++]="${var_t}"
done < /dev/stdin
else
var=( $* )
fi

(
for i in ${var[@]}
do
printf "ibase=2; %07d\n" "$(bc <<< "obase=2; ${i}")"
done
) | sort | bc
}

sort -V 2> /dev/null <<< "1"
[ $? -eq 0 ] && sort="sort -V" || sort="sortv"

cat <<EOL | ${sort}
1
10
2
20
EOL

출력 결과는

1
2
10
20


P.S.
기존의 sortv 함수가 문자열이나 공백이 들어갈 경우 문제가 되어 개선을 해 보았습니다.

function sortv {
local var
local i
if [[ $# == 0 ]]; then
i=0
while read var_t
do
var[i++]="${var_t}"
done < /dev/stdin
else
var=( $* )
fi

(
for i in "${var[@]}"
do
perl -p -e 's/([0-9]{4})/$1#~~#/g; s/([0-9]+)/`bc <<< "obase=2; $1" | xargs printf "%020d~~"`/eg' <<< "${i}"
done
) | sort | perl -pe 's/([0-9]{20})~~/`bc <<< "ibase=2; $1" | xargs printf "%s"`/eg; s/[0-9]{4}#~~#/$1/g'
}

sort -V 2> /dev/null <<< "1"
[ $? -eq 0 ] && sort="sort -V" || sort="sortv"

cat <<EOL | ${sort}
/home/0 asdfdsakf298u098uop;
/home/2 asdfdsakf298u097uop;
/home/5 asdfdsakf298u098uop;
/home/4 asdfdsakf298u098uop;
/home/11 asdfdsakf298u098uop;
/home/3 asdfdsakf298u028uop;
/home/1
EOL

출력 결과는 

/home/0  asdfdsakf298u98uop;
/home/1
/home/2 asdfdsakf298u97uop;
/home/3 asdfdsakf298u28uop;
/home/4 asdfdsakf298u98uop;
/home/5 asdfdsakf298u98uop;
/home/11 asdfdsakf298u98uop;
2020/01/16 18:47 2020/01/16 18:47
Posted
Filed under Tech/Tip & Trick
MegaRAID 의 VD 의 device name 을 구하는 방법

일단, controller 별 device 정보는 다음에서 구할 수 있다

/dev/disk/by-path/*
/sys/block/*/device


이 두 경로 리스트의 softlink target 에 device name 이 존재한다.

[root@host ~]# ls -l /dev/disk/by-path/
합계 0
lrwxrwxrwx 1 root root 9 9월 5 01:30 pci-0000:00:11.5-ata-3.0 -> ../../sdg
lrwxrwxrwx 1 root root 10 9월 5 01:30 pci-0000:00:11.5-ata-3.0-part1 -> ../../sdg1
lrwxrwxrwx 1 root root 10 9월 5 01:30 pci-0000:00:11.5-ata-3.0-part2 -> ../../sdg2
lrwxrwxrwx 1 root root 10 9월 5 01:30 pci-0000:00:11.5-ata-3.0-part3 -> ../../sdg3
lrwxrwxrwx 1 root root 9 9월 5 01:30 pci-0000:17:00.0-scsi-0:2:0:0 -> ../../sda
lrwxrwxrwx 1 root root 9 9월 5 01:30 pci-0000:17:00.0-scsi-0:2:1:0 -> ../../sdb
lrwxrwxrwx 1 root root 9 9월 5 01:30 pci-0000:b3:00.0-scsi-0:2:0:0 -> ../../sdc
lrwxrwxrwx 1 root root 9 9월 5 01:30 pci-0000:b3:00.0-scsi-0:2:1:0 -> ../../sdd
lrwxrwxrwx 1 root root 9 9월 5 01:30 pci-0000:b3:00.0-scsi-0:2:2:0 -> ../../sde
lrwxrwxrwx 1 root root 9 9월 5 01:30 pci-0000:b3:00.0-scsi-0:2:3:0 -> ../../sdf


by-path 의 장점은 위의 정보와 같아 cotroller 에 연결이 안되어 있는 disk 가 존재하는 경우을 처리할 수 있다는 장점이 있으나, CentOS 5 이전의 경우에는 by-path를 지원하지 않는 단점이 있다. CentOS 5 에서도 커널 버전에 따라 지원되고 안되고의 차이가 발생할 있다.

/sys 는 아래와 같다.

[root@a1page074.ndrive z]# ls -l /sys/block/sd*/device
lrwxrwxrwx 1 root root 0 8월 30 12:06 /sys/block/sda/device -> ../../../0:2:0:0
lrwxrwxrwx 1 root root 0 8월 30 12:06 /sys/block/sdb/device -> ../../../0:2:1:0
lrwxrwxrwx 1 root root 0 8월 30 12:06 /sys/block/sdc/device -> ../../../12:2:0:0
lrwxrwxrwx 1 root root 0 8월 30 12:06 /sys/block/sdd/device -> ../../../12:2:1:0
lrwxrwxrwx 1 root root 0 8월 30 12:06 /sys/block/sde/device -> ../../../12:2:2:0
lrwxrwxrwx 1 root root 0 8월 30 12:06 /sys/block/sdf/device -> ../../../12:2:3:0
lrwxrwxrwx 1 root root 0 8월 30 12:06 /sys/block/sdg/device -> ../../../3:0:0:0


/sys 의 경우 /sys 를 지원하는 커널에서는 다 사용을 할 수 있지만, 위와 같이 controller 에 연결이 되어 있지 않은 device 를 솎아 내기가 좀 애매하다.

여기서는 경우의 수를 될 수 있으면 많이 처리하기 위하여 /dev/disk/by-path 를 이용하여 구하는 코드를 만들어 볼 것이다.

일단, MegaRAID 를 사용하는 device 만 솎아 내기 위하여 PCI table 을 확인한다.

[root@host ~]# lspci | grep -E "LSI|Dell|IBM|MegaRAID"
17:00.0 RAID bus controller: LSI Logic / Symbios Logic MegaRAID SAS-3 3108 [Invader] (rev 02)
b3:00.0 RAID bus controller: LSI Logic / Symbios Logic MegaRAID SAS-3 3108 [Invader] (rev 02)


여기서 주의할 것이 sort 를 해서는 안된다. 여기에 나오는 순서가 MegaCLI 에서 나오는 controller 의 순서와 동일하다. 이 정보의 첫번째 필드만 있으면 된다.

그럼 by-path 에서 controller 정보와 VD 정보는 어떻게 매핑 하면 되는지 보겠다.

pci-0000:17:00.0-scsi-0:2:0:0
pci-0000:{PCI_TABLE_NUMBER}-scsi-0:2:{VD_NUMBER}:0


위와 같은 규칙을 이용하여 찾도록 한다. 그럼 완성된 코드는 다음과 같다.

idx=0
for rc in $(lspci | grep -E "LSI|Dell|IBM|MegaRAID" | sort | awk '{print $1}')
do
bypath="$(
ls -l /dev/disk/by-path/pci-0000:${rc}-* 2> /dev/null | awk -v ctrlidx=${idx} '
{
n = split ($(NF-2), A, ":");
vdnum = A[n-1]
dev = gensub (/.*\//, "", "g", $NF);

print ctrlidx ":" vdnum ":" dev

#print $(NF-2) " " $NF
}
'
)"
echo "$bypath"
let "idx++"
done


위의 코드의 결과는 다음과 같다.

controller_number:VD_number:device_name
0:0:sda
0:1:sdb
1:0:sdc
1:1:sdd
1:2:sde
1:3:sdf
2019/09/05 13:19 2019/09/05 13:19
Posted
Filed under Tech/Tip & Trick
MariaDB 10.4 부터 mysql database 의 user table 에 변경이 발생했습니다.

mysql> UPDATE USER SET Password = password('PASS_STRING');
mysql> flush privileges;

위와 같이 기존의 방식으로 변경을 하면 다음과 같은 에러가 발생 합니다.

ERROR 1348 (HY000): Column ‘Password’ is not updatable.

이 이유는, 10.4 부터는 user table 이 없어지고 global_priv table 이 그 역할을 대신 하기 때문입니다. show tables 시에 보여지는 user table은 global_priv 등의 table를 이용하여 view 로서 대신 하게 되었기 때문에 user table 을 update 하는 것이 불가능 합니다.
MariaDB [mysql]> SHOW FULL TABLES IN mysql WHERE TABLE_TYPE LIKE 'VIEW';
+-----------------+------------+
| Tables_in_mysql | Table_type |
+-----------------+------------+
| user | VIEW |
+-----------------+------------+
1 row in set (0.007 sec)

https://mariadb.com/kb/en/library/authentication-from-mariadb-104/

위의 문서를 읽어 보시면 몇가지 특징이 있는데, mysql 10.4 부터는 더이상 mysql 의 root 계정에 대한 암호를 기본적으로는 물어보지 않습니다. 이 이유는 오직 root account 로 mysql client 를 실행 했을 경우에만 암호가 없이 동작을 하며, 기타 다른 일반 account 로는 -u root 를 이용하여 접속이 불가능 함을 의미합니다. 즉, 일반 유저로 mysql root 연결이 필요 없다면, 더이상 mysql root 암호를 지정할 필요가 없다는 얘기입니다.

역설적으로 일반 account 에서 mysql root 로 연결을 할 필요가 있다면 mysql root 암호를 변경해 주어야 한다는 얘기도 됩니다.

여기서는 일반 account 에서 mysql root 로 연결을 하고 싶을 때 root account 의 암호를 변경하는 방법입니다.

일단은
SELECT password('PASSWORD_STRING');
query 를 이용하면 암호화된 문자열을 얻을 수 있습니다. 이 정보를 가지고 global_priv table의 Priv field 의 값을 수정해 주면 됩니다. (https://www.reddit.com/r/sysadmin/comments/avx1u6/how_to_change_the_root_password_with_mariadb_104/ 참조)

하지만 이렇게 하면 굉장히 번거롭기 때문에 다음과 같이 query 하나로도 변경이 가능 합니다.

ALTER USER 'root'@'localhost' IDENTIFIED BY 'PASSWORD_STRING';




단, mariadb 10.3 이하 버전에서 업그레이드를 하여 mysql_upgrade 를 실행한 경우에는, 위의 조건이 성립하지 않습니다. mysql_upgrade 를 이용하여 mysql table을 10.4 용으로 업그레이드 한 경우에는 기본의 mysql database 의  table 들이 유지가 되게 됩니다. 즉, 이 경우에는 global_priv database 가 생성이 되지 않고 user table 이 view가 아니라 여전히 table 이 되게 됩니다.
2019/08/12 16:37 2019/08/12 16:37
Posted
Filed under Tech/안녕리눅스
TLS 1.3 지원을 하려면 openssl 1.1 이상이 필요 합니다.
현재 CentOS 7 이나 안녕 3 에서는 지원이 안된다는 얘기죠. 물론 openssl 1.1 을 별도 위치에 설치해 놓고 link를 하는 방법은 가능 합니다. 단순히 배포본 기본 패키지로 지원을 하지 않는 다는 것을 언급 하는 것입니다.

일단, 안녕 3에 TLS 1.3 지원을 위하여 openssl 1.1 관련  compat 패키지들을 등록해 놓았습니다. 조만간 SSL을 사용하는 패키지들을 모두 openssl 1.1 로 link를 변경하여 안녕 3에서 지원이 가능하게 할 예정 입니다.

작업을 마치면, CentOS 7 에서 이 패키지들을 사용할 수 있는 방법도 올려 보도록 하겠습니다.
2019/06/02 23:43 2019/06/02 23:43