2017년 8월 15일 화요일

Windows 10에서 창 배경색(메모장 배경 색) 변경하기





윈도 10에서 메모장을 열면 백색의 강렬함이 눈을 자극한다. 몹시...
그런데 이걸 바꿀수 있는 기능이 이전 윈도우들에서는 제공이 되었으나 지금은 없는 듯 하다.
발전은 못할망정 이건 뭐...
하는 수 없이 윈도우의 레지스트리 변경을 통해 하는 수 밖에 없다.
근데 이건 조심하지 않으면 땀 나는 경우가 있다.
다음 순서로 진행한다

-. 윈도우 키 + R
-. regedit
-. HKEY_CURRENT_USER
-. Control Panel
-. Colors

우측에 여러 항목들이 나타난다. 이들 중에서 
Window라는 항목에 데이터 값이 255 255 255로 되어 있을 것이다.
이 값을 변경하면 윈도의 창 배경색이 바뀐다. 메모장, 아래아 한글...
255 255 255는 차례대로 Red Green Blue의 색상 값이다.

이 색상 값을 어떻게 변경할지를 참조할 사이트는

https://www.w3schools.com/colors/colors_picker.asp

이곳에서 색상의 값과 색상이 어떤 색인지를 확인해서 값을 변경하면 된다.
데이터 값 변경은 해당 항목(Window)에 마우스 우측 클릭 후 "수정" 메뉴 클릭해서 변경하면 된다.

그 다음 항목으로 Window Text 항목이 있는데 이 항목의 데이터 값은 0 0 0으로 되어 있을 것이다.
이것은 글자 색이 검정색임을 의미한다.

이후 PC를 재 부팅한다.

단 이상의 색상들을 변경함으로 인해 윈도우 다른 프로그램들에서 글자가 안 보이는 현상이 없도록 색상 조합을 잘 해줘야 한다.
미덥지 않으면 기존의 색상 값을 다른 곳에 잘 저장해 둘 필요도 있고 혹은 레지스트리 값을 백업해 둘 필요도 있다.

2017년 8월 8일 화요일

리눅스 터미널 창을 탭으로 열기





리눅스에서 터미널을 여러개 띄워놓고 작업을 할 경우 마우스로 드래그해 가면서 창의 크기를 조절해서 화면분할해 가면서 사용해야 하는 불편함이 있다.
이를 보다 간편하게 해결할수 있는 기능이 탭 기능이다.

Ctrl-Shift-T를 하면 현재의 터미널 상에서 새로운 탭(크롬과 같은 웹 브라우저에서 새 탭에서 웹 페이지 여는 것과 같은...)이 생기면서 새로운 터미널 창을 열수 있다.
이렇게 여러개의 탭으로 터미널을 열면 작업하기가 무지 편해 진다.



탭 간의 이동은
 -. Alt + 1/2/3... 으로 각 탭으로 이동하는 방식과
 -. Ctrl + PageUp/PageDown으로 각 탭으로 이동하는 방식이 있다.
위의 방식이 보다 쉬운 방식이리라...

현재 탭 닫기는
Ctrl + Shift + w


2017년 8월 3일 목요일

C++ 2차원 포인터(포인터의 포인터)를 이용한 2차원 배열 다루기





본 프로그램은 n명의 학생 각각이 m개의 과목을 수강할 경우에 대한 
2차원 배열을 선언하는 형태인데 학생 수가 고정되어 있지 않고 가변이고
각 학생의 수강 과목도 고정되어 있지 않고 각각 상이하다고 할 때의 
상황이다. 이때 가장 적합한 2차원 배열의 형태가 "2차원 포인터(포인터의 포인터)"
형태로 선언하는 것에 대한 예제 코드이다.

#include <iostream>
#include <malloc.h>

using namespace std;

void main()
{
//2차원 포인터는 2차원 배열의 형태를 갖는데 
//세로(행, row)도 가변적인 배열, 가로(열, column)도 가변의 크기를 갖는 배열이라는 뜻
int** score;
int studentNum = 0;
int lessonNum = 0;
int allTotalSize = 0;

cout << "학생 수 입력 : ";
cin >> studentNum;

//studentNum 갯수 만큼의 크기를 가진 배열이 선언되는데 이 배열의 각 원소가
//int형 포인터 변수이므로 각 원소가 또 동적 할당으로 임의 크기의 배열의 시작 주소를
//가리키게 되므로 결국 2차원 배열이 되는 것이다.
//즉 studentNum 갯수 만큼의 크기를 가진 int형 포인터 변수가 배열 형태로
//선언되고 그 시작 주소 값을 score에 저장한다.
//통상적으로 이렇게 생성되는 배열을 2차원 배열의 행(row, 가로)의 크기로 본다.
score = new int*[studentNum];
cout << "sizeof(score) : " << sizeof(score) << " byte" << endl;
cout << "_msize(score) : " << _msize(score) << " byte" << endl << endl;

//_msize()함수에 대해: new로 생성된 메모리는 heap 메모리 영역에 생성되고
//heap 메모리 영역은 운영체자가 관리해 주기 때문에 동적 할당된 메모리의 크기를
//알기 위해서는 운영체제의 도움이 필요하다.
//윈도우의 경우 _msize()함수를 통해 알수 있다.
//반면에 sizeof()함수는 포인터 변수 자체의 크기를 반환하는데 포인터 변수는 
    //항상 4byte로 동일하다
//아래의 코드는 score가 가리키는 동적 할당된 메모리 전체의 크기를 반환한다.
//score = new int*[studentNum]으로 할당되었기에 
//studentNum * 4(int형의 크기가 4byte이므로)의 크기를 가진다.
allTotalSize = _msize(score);

//studentNum 갯수 만큼의 배열 각 요소인 int형 포인터 변수 각각에 대해
//동적 메모리 할당을 통해 또 다시 배열을 만든다. 따라서 2차원 배열이 되는 것이다.
//통상적으로 이렇게 생성되는 배열을 2차원 배열의 열(column, 세로)의 크기로 본다.
for (int i = 0; i < studentNum; i++)
{
cout << (i+1) << "번 학생의 수강 과목 수 : ";
cin >> lessonNum;

score[i] = new int[lessonNum];
allTotalSize += _msize(score[i]);
cout << (i + 1) << "번째 배열의 크기 : " << _msize(score[i]) << " byte" 
                                                                                            << endl << endl;
}

cout << endl << "2차원 포인터 배열 전체의 크기 : " << allTotalSize << " byte" 
                                                                                            << endl;

//여기서 성적 입력 및 평균, 총점 처리...

//메모리 해제(동적 할당된 메모리는 사용후 반드 해재해 줘야함!)
for (int i = 0; i < studentNum; i++)
{
delete[] score[i];
//delete score[i]; //이 경우는 i번째 배열 전체가 아닌 그 배열의 시작 주소만 해제 함
}

delete[] score;

cout << endl << "동적 할당 메모리 해제 완료~" << endl;
}

실행 결과는 다음과 같다.



2017년 7월 25일 화요일

몇 가지 리눅스 명령어





몇 가지 리눅스 명령어

1) getconf LONG_BIT
 -. 현재의 리눅스 시스템이 32비트인지 64비트인지 확인
 -. 예) # getconf LONG_BIT

리눅스 상에서 가끔 실행파일을 실행시켜 보면 "cannot execute binary file: Exec 형식 오류"과 같은 에러가 발생할수가 있다. 이건 리눅스가 32비트인데 64비트 실행파일을 실행하고자 할때의 경우에 발생한다.

2) wget
 -. http, https, ftp 프로토콜을 이용하여서 웹에 있는 특정 파일을 다운로드
 -. 예) wget http://www.som.co.kr/qt-opensource-linux-x64-5.8.0.run

리눅스의 웹 브라우저등으로 웹 상의 파일을 다운로드 할수도 있으나 부득이 터미널 창에서 웹의 파일을 다운로드 받아야 할 경우 wget으로 편리하게 다운로드 받을수 있다.

3) apt-cache pkgnames | grep 패키지_이름
 -. 현재의 리눅스에 설치되어 있는 패키지 프로그램을 찾고자 할 때 사용
 -. 예) apt-cache pkgnames | grep wget
        (wget이 설치되어 있는지 확인할수 있다)

4) lpq 
 -. 프린트 큐에 있는 작업의 목록을 보여주는 명령어
 -. 예) lpq
         EPSON-L365-Series is ready
         no entries

5) cat /proc/cpuinfo
-. cpu에 대한 전체적인 정보가 나온다.

6) dpkg --print-architecture
-. Linux Kernel architecture 확인
-. 여기서 나오는 정보는 amd64, arm64, armhf, i386 등의 정보가 나온다.

7) ls -sh
-. 파일 목록을 보여줄때 파일 사이즈를 Kb, Mb의 형식으로 표시
   (파일이름과 사이즈 정보만 표시됨). 디폴트는 byte단위로 표시됨
-. 여기서 s는 size, h는 human readable형식을 뜻한다.
-. 만일 자세한 정보를 같이 표시할려면 ls -lsh



memcpy()함수를 이용한 문자열 복사 하기





memcpy()함수를 이용한 문자열 복사 하기

char *name = "홍 길동";

//strlen() : 현재 문자열의 크기 값을 반환
//size_t strlen(const char *_Str)
//따라서 매개인자의 데이터 타입은 char* 형
char *kkk = new char[strlen(name) + 1];

//만일 char *kkk = new char[strlen(name) + 1]의 작업 없이 
//char *kkk;로만 선언후 memcpy(kkk, name, strlen(name))과 같이 하면
//이 경우는 "초기화되지 않은 'kkk' 지역 변수를 사용했습니다."라는 에러 발생.
//이유는 메모리 할당되지 않은 상태에서 memcpy()로 복사하고자 했기 때문이다.

//memcpy() : void *memcpy(void *dest, const void *src, size_t count)
//아래는 name에 있는 문자열을 kkk에 복사를 하되 strlen(name)+1만큼 복사
memcpy(kkk, name, strlen(name));

//printf("kkk : %s\n", kkk);
//cout << "kkk : " << *kkk << endl; //not work
cout << "kkk : " << kkk << endl; //work


2017년 7월 21일 금요일

윈도우에서 양방향 ping 설정하기





네트워크 연결 상태를 체크할 때 가장 손쉬운 방법이 ping을 통해서 테스트해 보는 방식이다.
그런데 윈도우쪽에서 다른 쪽으로 ping이 정상적으로 전송되는데 반대로
그 다른 쪽에서 윈도우쪽으로는 ping이 불가능할 때가 있다.
이때 콘솔 창(DOS 창)을 관리자 권한으로 연 후 아래 명령어를 입력하면 해결 끝

netsh advfirewall firewall add rule name="ICMP Allow" protocol=icmpv4:8,any dir=in action=allow

관련된 자세한 정보를 볼려면

netsh advfirewall firewall show rule name="ICMP Allow" dir=in type=dynamic

2017년 7월 18일 화요일

MFC 개발시 콘솔창(DOS 창)에 로그 출력하기.





MFC 개발시 콘솔창(DOS 창)에 로그 출력하기.

MFC 개발시 프로그램 실행의 정보를 콘솔 창에 로그로 출력하기 위해서는 
stdafx.cpp안에 아래 코드를 추가하면 프로그램이 실행될 때 콘솔 창이 뜨고 printf()나 cout으로 출력하는 값이 표시가 된다.

#pragma comment(linker, "/entry:WinMainCRTStartup /subsystem:console")    //semicolon이 없음

TestView.cpp에서 특정 변수의 값을 콘솔창에 출력하고 싶다면

#include <iostream> //cout으로 출력하기 위해

... 중 략 ...

std::cout << "x : " << point.x << std::endl;
printf("결과 : %d\n", point.x);

과 같이 사용하면 된다.


2017년 7월 11일 화요일

Ubuntu root 계정 암호(비밀번호) 생성





우분투는 최초 설치 후 기본적으로 root 계정으로 접속할수 없다. root 계정은 만들어져 있으나 암호 설정이 되어 있지 않다. 이럴 때 우분투 초기 설치후 root 계정의 비밀번호를 생성해 주면 된다.
방법은 다음과 같이...

$ sudo passwd root
[sudo] password for 현재로그인한사용자: <여기에서 현재 로그인한 사용자의 비번을 입력한다>
새 UNIX 암호 입력 : <여기에 root 비번입력>
새 UNIX 암호 재입력 : <여기에 root 비번 다시 입력>
passwd: 암호를 성공적으로 업데이트했습니다.

$ su
암호: <여기에 root 비번 입력>

root@.... # 

위와 같이 prompt가 #로 바뀌면 root 계정으로 정상적으로 로그인한 것이다.

2017년 6월 20일 화요일

Data too long for column 에러 해법 : MySQL의 sql_mode 변경하기





MySQL table에 데이터를 insert하다보면  
Data truncation: Data too long for column '에러가_발생한_필드' at row 1
과 같은 에러를 만나는 경우가 있다.

에러 메시지 자체만 놓고 보면 특정 필드(column)의 선언된 크기보다 insert 될 데이터의 크기가 더 크기 때문으로 보인다.
그런 경우도 있으나 MySQL의 환경 설정상의 원인으로 인한 경우도 있다.
MySQL의 mode가 STRICT인 경우에 위와 같은 에러가 빈번히 발생할수 있다.

MySQL의 설정 파일인 my.cnf에 sql_mode의 값이 STRICT_TRANS_TABLES일 경우 필드에 선언된 대로의 값이 주어지지 않으면 위와같은 에러를 발생시키고 쿼리문을 중단한다.
현재의 sql_mode가 어떤 내용인지를 확인할려면 my.cnf를 열어서 확인할수도 있고 아래와 같이 MySQL에 접속한 상태에서 

# mysql -umysql아이디 -p로 mysql에 접속한 상태에서 select @@global.sql_mode 명령어로 현재의 sql-mode를 확인할수 있다.

mysql> select @@global.sql_mode;
+----------------------------------+
| @@global.sql_mode              |
+----------------------------------+
| NO_ENGINE_SUBSTITUTION    |
+----------------------------------+

sql_mode가 STRICT일 경우는 insert 작업을 까다롭게 관리해서 데이터의 무결성을 위해서는 좋으나 사실은 번거로운 상황이다.
STRICT모드를 변경할려면 my.cnf의 sql_mode의 내용을 변경해 주면 된다.
CentOS의 경우 

# vi /etc/my.cnf 파일을 열어서

# Recommended in standard MySQL setup
sql_mode=NO_ENGINE_SUBSTITUTION, STRICT_TRANS_TABLES

sql_mode에서 STRICT_TRANS_TABLES를 제거하거나 아니면 sql_mode 자체를 주석처리해서 사용하지 않도록 하면된다.

저장 후 mysql 데몬을 재 시작해 준다.

# service mysqld restart

2017년 6월 1일 목요일

MySQL 한글 insert시 발생하는 ERROR 1366 (HY000): Incorrect string value: 문제





MySQL 테이블의 특정 필드에 한글을 insert하다보면 아래와 같은 에러가 발생하는 경우를 만날수 있다.
ERROR 1366 (HY000): Incorrect string value: ...

kkk라는 테이블이 아래와 같은 형식으로 생성되어 있다고 가정하면,

mysql> show create table kkk;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                             |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
| kkk   | CREATE TABLE `kkk` (
  `bdid` bigint(11) unsigned NOT NULL,
  `name` varchar(80) NOT NULL,
  PRIMARY KEY (`bdid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

위와 같이 kkk라는 테이블이 있을 경우 DEFAULT CHARSET=latin1으로 되어 있다.
이때 한글을 name 필드에 insert하게 되면 아래와 같은 에러가 발생한다.

mysql> insert into kkk (bdid, name) values (1, '한글입력');
ERROR 1366 (HY000): Incorrect string value: '\xED\x95\x9C\xEA\xB8\x80...' for column 'name' at row 1

이 문제 해결을 위해서는 default character set을 utf8로 변경해 주면 깨끗이 해결된다.
kkk라는 테이블을 생성하는 DDL 문에서 아예 utf8로 설정해서 테이블을 생성해 주면 된다.
다음과 같이

CREATE TABLE `kkk` (
  `bdid` bigint(11) unsigned NOT NULL,
  `name` varchar(80) NOT NULL,
  PRIMARY KEY (`bdid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

MySQL table의 필드 값이 한글일 경우 Java 소스에서 SELECT 실패할 경우





MySQL 필드의 내용이 한글 일 경우 Java 소스코드 상 SELECT문의 비교문에서 인식이 안되는 문제가 있다.

mysql> select * from board;
+------+-----------------+
| bdid | name            |
+------+-----------------+
|    1 | 공지사항        |
|    2 | QandA           |
|    3 | 자유게시판      |
|    4 | menu            |
+------+-----------------+

board라는 테이블의 내용이 위와 같다고 할 경우

select bdid from board where name = '자유게시판';
과 같은 구문에서 bdid의 값 3이 추출되지 않는다.

만일 select bdid from board where name = 'QandA';
와 같이 한글이 아닌 영문일 경우는 정상적으로 bdid의 값 2를 추출할 수 있다.

이 문제는 MySQL의 환경설정 중 character set상에서의 문제이다.

mysql> show variables like '%chara%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | latin1                     |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+

비록 위와 같이 MySQL variagle들이 utf8로 설정되어 있다하더라도 
/etc/my.cnf라는 설정 파일을 아래와 같이 charater set을 모두 설정해 주어야 한글이 정상적으로 select문에서 작동하게 된다.

[client]
default-character-set = utf8

[mysql]
default-character-set = utf8

[mysqld]
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

character-set-server = utf8
collation-server = utf8_general_ci
init_connect=SET collation_connection = utf8_general_ci
init_connect=set NAMES utf8

character-set-client-handshake = FALSE
skip-character-set-client-handshake
wait_timeout=31536000

[mysqldump]
default-character-set = utf8

# Disabling symbolic-links is recommended to prevent assorted security risks
#symbolic-links=0

# Recommended in standard MySQL setup
#sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

위와 같이 설정 후 MySQL 데몬을 재가동해 준다.
# service mysqld restart

2017년 5월 31일 수요일

MySQL table로부터 DDL 추출하기





Database의 DB table이 생성되어 있을 때 이들 table 생성시 사용했던 DDL(Data Definition Language)를 보고 싶을 경우가 있다.
한마디로 이미 생성되어 있는 DB table들의 DDL을 뽑아내는 방법에 대한 것이다.

명령어 구문은(MySQL에 접속한 상태에서)

mysql> show create table 테이블명;

mysql> show create table kkk;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                             |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
| kkk   | CREATE TABLE `kkk` (
  `bdid` bigint(11) unsigned NOT NULL,
  `name` varchar(80) NOT NULL,
  PRIMARY KEY (`bdid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

kkk라는 테이블을 생성한 DDL 구문이다.

여기서 ENGINE의 종류는 InnoDB이다. MySQL의 경우 2가지 엔진 타입이 있는 InnoDB와 MyISAM이 있다.
InnoDB의 경우는 빈번한 쓰기, 수정, 삭제가 발생할 경우 유리하고
MyISAM은 InnoDB에 비해 상대적으로 성능이 높은 편인데 주로 읽기 위주의 처리에 높은 성능을 발휘한다.
반면에 MyISAM은 빈번한 쓰기, 수정, 삭제가 발생하는 경우라면 오히려 InnoDB보다 성능이 못하다고 한다.
정답은 상황에 맞게...

여기서 또 한가 주목할 부분은 DEFAULT CHARSET=latin1을 되어 있다.
이럴 경우 한글을 insert할 때 에러가 발생한다.
이 문제에 대한 해법은 다음 링크 참조.

default charset과 한글 입력 문제 바로가기

2017년 5월 26일 금요일

apache 포트 변경 및 웹 루트 변경하기





apache 포트 변경 및 웹 루트 변경하기

(1) CentOS

CentOS의 경우 apache 포트 번호 변경은 
/etc/httpd/conf/httpd.conf 파일을 열어서

Listen 80

과 같이 되어 있는 번호를 원하는 포트 번호로 변경하면 된다.
변경 후 apache를 재구동해 준다.

# service httpd restart

웹 루트 디렉토리 변경
/etc/httpd/conf/httpd.conf 파일을 열어서

DocumentRoot "/var/www/html"

과 같이 되어 있는 부분을 원하는 경로로 변경해 주면 된다. 다음과 같이..

DocumentRoot "/var/www/myhome"

변경 후 apache를 재구동해 준다.

# service httpd restart


(2) Ubuntu

우분투의 경우 apache 포트 번호 변경은

/etc/apache2/ports.conf 파일에서 

Listen 80

으로 되어 있는 부분을 원하는 포트 번호로 변경하면 된다.
변경 후 apache를 재구동해 준다.

# service apache2 restart

웹 루트 디렉토리 변경은
/etc/apache2/sites-available/000-default.conf 파일을 열면

DocumentRoot /var/www/html

과 같이 되어 있을 것이다. 디폴트 웹 루트 디렉토리이다. 이 디렉토리에 index.html과 같은 웹 페이지를 작성해 두면 http://xxx.xxx.xxx.x/index.html로 접근하는 경로이다.
그런데 /var/www/html을 /var/www/myhome으로 변경하고자 한다면
DocumentRoot /var/www/myhome으로 변경한 후 apache를 재 구동해 주면 된다.

# serivce apache2 restart

2017년 5월 17일 수요일

mysqlimport명령어를 이용하여 로컬의 텍스트 파일이나 dump파일을 MySQL db의 table에 값 저장하기





mysql의 table을 생성할 때 로컬의 특정 파일이 담고 있는 내용을 table의 값으로 저장해야하는 경우가 있다.
이때 로컬의 특정 파일은 dump 파일 일수도 있고, 일반적인 txt 파일 일수도 있다.

test.txt에 ,로 구분되어 다음과 같은 내용이 담겨 있다고 하면

홍길동,남,010-1234-4567,YES
장길동,여,011-0123-1111,NO
...

이 내용을 mysql의 특정 table의 내용으로 저장하는 작업을 할수도 있다.


혹은 로컬의 특정 파일의 내용이 다음과 같이 |로 필드의 값이 구분되어 있다고 할 경우

12      |       74109    |
30      |       29        |
36      |       184914  |
37      |       42        |
46      |       39        |
67      |       32033   |
76      |       155892  |
77      |       74311   |
79      |       74313   |
80      |       155892 |
90      |       34102   |
91      |       34103   |
.....

이럴 경우 mysqlimport 명령어를 이용하면 된다.

mysqlimport -uroot -p --local --fields-terminated-by="|" yyy  merged.dmp

여기서 -uroot는 mysql 사용자 계정의 id가 root라는 뜻이고 -p옵션은 mysql 사용자 계정의 비번을 입력하겠다는 것이다.
이 경우는 비번을 입력하지 않으면 위의 명령어를 실행할 때 비번을 묻게 된다.

--local 옵션을 주지 않으면 로컬 파일인 merged.dmp를 읽지 못하고 다음과 같은 에러를 발생 시킨다.

mysqlimport: Error: 13, Can't get stat of '/var/lib/mysql/yyy/merged.dmp' (Errcode: 2 - No such file or directory), when using table: merged

이 에러는 DB 명으로 입력한 yyy를 디렉토리 경로로 인식하는 문제다.

그 다음 옵션인 --fields-terminated-by="|"는 table저장할 데이터가 들어 있는 merged.dmp의 내용이 위에서 보는바와 같이 |를 기준으로 필드의 값이 구분되어 있다.
따라서 필드 구분자를 지정해 줘야 한다. 만일 ,로 구분되어 있다면 --fields-terminated-by=","와 같이 하면된다.

그다음 옵션인 yyy는 Database 이름이다. yyy라는 데이터베이스 안에 merged라는 table에 merged.dmp가 가지고 있는 내용을 table의 각 레코드와 필드에 값을 저장하게 된다.
이때 만일 다음과 같은 에러가 발생할 것이다.

mysqlimport: Error: 1290, The MySQL server is running with the --secure-file-priv option so it cannot execute this statement, when using table: merged

이 에러는 보안 상의 이유로 특정 디렉토리에 있는 파일에 대해서만 위의 명령어를 실행할수 있도록 설정되어 있다는 뜻이고 그 특정 디렉토리가 어느 곳인지를 알려면

mysql -u사용자id -p사용자비번

으로 들어가서

mysql>show variables like 'secure%';

를 실행하면

+------------------+--------------------------+
| Variable_name    | Value             |
+------------------+--------------------------+
| secure_auth      | ON                  |
| secure_file_priv  | /aaa/bbb/ccc/     |
+------------------+---------------------------+

와 같은 정보가 나올 것이다. 이것은 /aaa/bbb/ccc/라는 디렉토리에서만 mysqlimport로 특정 파일의 내용을 mysql db의 table에 값을 저장할수 있다는 뜻이다.

만일 secure-file-priv 자체를 off 시키고 싶다면
우분투의 경우 /etc/mysql/mysql.cnf 파일 안의 맨 끝에
secure-file-priv=""를 한줄 추가한 후

# service mysql restart

를 실행해서 mysql을 재실행해 주면 mysql.cnf의 설정대로 적용이 되어 secure-file-priv를 off하게 된다.

보안을 위해 이 작업 후에는 역시 mysql.cnf의
secure-file-priv="/aaa/bbb/ccc/"로 변경후 역시 mysql을 restart시키는 것이 신상에 좋을 것이다.

혹은 mysqlimport와 동일한 기능을 다음과 같이도 가능하다.
mysql에 접속해서(mysql -u사용자id -p)

mysql> LOAD DATA INFILE '/var/lib/mysql-files/merged.dmp' INTO TABLE merged FIELDS TERMINATED BY '\t|\t' LINES TERMINATED BY '\t|\n' (old_tax_id, new_tax_id);

여기서 /var/lib/mysql-files/merged.dmp는 mysql db의 table에 저장할 데이터가 들어 있는 로컬의 (텍스트)파일,

FIELDS TERMINATED BY '\t|\t'는 /var/lib/mysql-files/merged.dmp 파일의 필드 구분자가 '\t|\t'라는 뜻이고

LINES TERMINATED BY '\t|\n'는 /var/lib/mysql-files/merged.dmp 파일의 row(레코드) 구분자가 '\t|\n'라는 뜻이고

(old_tax_id, new_tax_id)는 /var/lib/mysql-files/merged.dmp 파일의 내용을 읽어서 저장할 merged라는 table의 필드명이다.

대용량 데이터를 처리해본 결과 mysqlimport에 비해서 LOAD DATA INFILE의 방식이 훨씬 안정적으로 동작했다.

2017년 3월 22일 수요일

JSP 변수를 자바스크립트(JavaScript)에서 사용하는 법





JSP로 웹 프로젝트를 개발하다 보면 JSP의 변수를 JavaScript에서 사용해야 할 일이 종종발생한다.
간단한 JSP 변수로부터 ArrayList의 값을 자바스크립트에서 사용해야 할 경우도 있다.
아래 코드는 JSP의 변수를 JavaScript에서 사용하는 간단한 코드이다.

<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>Insert title here</title>
</head>
<body>
<!-- 
아래 코드는 JSP의 변수를 자바스크립트에서 사용하는 방법에 대한 코드이다.
 -->
<script type="text/javascript">
<%
ArrayList<String> arr = new ArrayList<String>();
arr.add(0, "첫 번째");
arr.add(1, "두 번째");
arr.add(2, "세 번째");
arr.add(3, "네 번째");
arr.add(4, "다섯 번째");
for(int i=0; i<5; i++)
{
%>
//alert("i: "+ i); //이런 식으로는 다음 에러 발생 Uncaught ReferenceError: i is not defined 
//이런식으로 해야 정상적으로 JSP 변수의 값을 자바스크립트에서 사용 가능
//JSP쪽 변수 i의 값을 자바스크립트에서 다음과 같이 사용한다.
alert("i~: " + <%= i %>); 
//아래 코드의 경우는 다음 에러 발생. Uncaught SyntaxError: missing ) after argument list
//따옴표로 감싸야한다. 왜냐하면 데이터가 문자열이기 때문이다.
//console.log("arr : ", <%= arr.get(i) %>); 
console.log("arr[", <%= i %>, "] ⇒ ", '<%= arr.get(i) %>'); //가능
//위 console.log()에서 다음과 같이 출력된다.
//arr[ 0 ] ⇒  첫 번째
//arr[ 1 ] ⇒  두 번째
//arr[ 2 ] ⇒  세 번째
//arr[ 3 ] ⇒  네 번째
//arr[ 4 ] ⇒  다섯 번째
<%
}
%>

</script>
</body>
</html>

2017년 3월 9일 목요일

mysqldump시 unknown variable 'symbolic-links=0'라는 에러에 대해






centos 7.0하에서 mysqldump로 DB를 백업받고자 다음과 같이 하면

# mysqldump -u사용자id -p DB명 > 백업할_파일명
ex) # mysqldump -uuserid -p testDB > mybackup.sql
과 같이하면 아래와 같은 에러가 발생하는 경우가 있다.

mysqldump: unknown variable 'symbolic-links=0'

해법은 /etc 디렉토리 아래에 있는 my.cnf 파일을 vi로 열어서

symbolic-links=0

를 주석처리하면 된다.

그런 다음 mysqld를 restart해 줘야 한다.

# service mysqld restart

혹 위의 작업을 했는데 mysqldump 명령시 다음과 같은 에러가 발생한다면

mysqldump: unknown variable 'sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES'

역시 my.cnf 파일에서 아래를 주석처리하면 된다.

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

그런데 이상의 항목을 주석처리하고 db를 dump 후에는 원상복귀하는 것이 보안상 좋을것이다.

Servlet에서 로그 출력 및 확인하기





Java, JSP로 웹 프로그래밍을 하다 보면 로그를 출력해서 데이터의 흐름을 봐야할 때가 있다.
로그를 출력하는 것이야 모든 프로그램들이 다 기능을 제공해 준다.

JSP의 경우는 JavaScript의 alert()이나 console.log()를 이용해서 웹브라우저에서 확인할수가 있으나
Servlet 상에서 변수의 값을 로그로 출력할경우는 alert()이나 console.log()를 사용하기가 어려워진다.

Servlet의 경우는 보통 System.out.println()과 같은 방식으로 로그를 확인할수 있겠는데
local상에서 개발할 때는 물론 이클립스의 경우 로그를 볼수가 있다.
그러나 웹 서버에서 돌아가는 Servlet에서 System.out.println()의 결과를 어떻게 확인해야할지 난감해진다.
그런데 의외로 간단하게 이 문제를 해결할수 있다.

tomcat이 설치되어 있는 디렉토리의 하위에 logs라는 디렉토리가 있고 logs 디렉토리에는
많은 종류의 로그 파일들이 저장되어 있다.
이 디렉토리에 가면 catalina.out이라는 로그 파일이 있는데 여기에 System.out.println()에서 출력한 값들이 저장되어 있다.
이 파일을 vi로 열어서 확인하면 웹 서버 상에서 돌아가는 Servlet의 로그를 확인할수가 있다.