2018년 12월 23일 일요일

리눅스 명령어 간단 정리

기본적인 리눅스 명령어 (책)

cd : 디렉토리 변경(change directory)
  cd .. : 상위 디렉토리로 이동
  cd : 홈 디렉토리로 이동
  pwd : 현재 디렉토리 위치
ls(list segments) : 디렉토리 및 파일 정보 화면에 출력
  -l : 긴 리스트 형으로 화면에 출력
history : 사용자가 입력한 명령어들의 기록을 보여줌
alias : 사용자 정의 명령어
  ex) alias ex1 = "clear"  ex1 입력하면 clear 실행됨
      alias 입력 시 설정된 내용 조회 가능
      unalias ex1 로 해제가능
rm : 파일이나 디렉토리 삭제
  -r 디렉터리 삭제, 하위 내용을 먼저 삭제
  -f / --force / 강제로 파일이나 디렉토리를 삭제하고, 삭제할 대상이 없을 경우 메시지를 출력하지 않음
  -i  매번 삭제할 때마다 사용자에게 질문함
  -v 삭제하는 내용 보여줌
mv : 파일 및 디렉토리 이동, 이름 변경
  -b 백업 파일을 생성
  -f 사용자에 묻지 않고 파일 덮어씀
  -i 덮어쓸 경우 사용자에게 물어봄
  -n 파일이 존재하면 덮어쓰지 않음
  -S 지정한 접미사로 백업생성
  -t 전체 원본파일을 대상 디렉토리로 이동
  -u 파일이 업데이트된 경우에만 이동함
  -v 진행상태 정보를 출력
| (pipe) : 어떤 명령어의 실행 결과를 다른 명령어의 입력으로 전달하는 것
  ex) ls -l | grep "tom"
crontab : 시스템에서 주기적으로 실행하는 명령어 설정
  -l 현재 로그인된 계정에 잡혀있는 작업 스케쥴 확인
  -e 현재 로그인 중인 계정에 작업을 등록  
  (0 0 * * 0 /bin/myjob.sh ---> 매월 일요일 0시 0분에 /bin/myjob.sh 실행
  분 시 일 월 요일)
  -r 현재 crontab에 등록된 작업을 삭제
gzip : 파일압축
  -n 1~9, 1이 가장 빠르고 압축률은 가장 낮음
  -c 압축결과를 출력, 원본파일은 그대로 둠
  -d 압축해제
  -f 강제압축
  -l 압축파일의 정보 출력
  -r 디렉토리에 포함된 모든 파일을 압축
  -t 압축파일 테스트
  -v 압축 혹은 해제 시 정보출력
tar : 파일을 압출하거나 해제하는 명령어
  -z gzip으로 압축하거나 해제
  -x 압축을 해제함
  -h 심볼릭 링크는 묶지 않고 심볼릭 링크가 가리키는 파일을 묶음
  -c 새 저장파일을 만듦
  -f 파일이름 지정
  -m 파일의 변경 시간정보를 유지하지 않음
  -P 모든 퍼미션 정보를 유지
  -p 파일 이름의 맨 앞, 문자를 버리지 않음
  -s 저장 파일 목록과 똑같은 순서로 압축을 해제
  -v 처리 중인 파일을 자세하게 보여줌
  -Z Compress 압축하거나 해제
which : 리눅스에서 사용하는 명령어의 경로를 찾아서 화면에 출력 (whereis는 관련파일까지 제공)
mkdir : 디렉토리 생성
  -m 디렉토리 권한 설정 (기본 755 rxwr-xr-x)
  -p 상위 경로도 함께 지정
  -v 디렉토리 생성 후에 생성된 디렉토리에 대한 메시지를 출력함
cp : 파일 혹은 디렉토리를 복사
  -f 덮어쓰기를 해서 복사
  -r 하위 디렉토리 전부를 모두 복사
  ex) cp test1 test2  ---> test1파일을 test2파일로 복사
touch : 파일을 생성하거나 파일의 시간정보 변경
  ex) touch test1.txt ---> 파일이없으면 생성
  touch -t 1801220333 ---> 18년 1월 22일 3시 33분으러 시간정보 변경
  touch -r test1 test2 --> test1파일과 test2파일의 시간정보를 같게 변경
file : 파일의 종류확인
  -b 파일의 유형만 출력
  -f 파일목록에서 지정한 파일들에 대해서만 명령을 실행
  -i MIME 타입형태로 출력
  -m 매직 파일을 지정
  -L 심볼릭 링크된 파일을 추적
  -v 버전 정보 출력
  -z 압축된 파일 확인
cat : 파일의 내용을 확인할 수 있는 명령어
head : 파일을 읽어 첫줄부터 10번째 줄까지 화면에 출력
tail: 파일을 끝부터 읽어 10번째 줄까지 화면에 출력
grep : 특정파일 내에 있는 문자열을 검색하는 역할을하는 명령어
  -c 검색 문자열이 속한 행 수를 출력
  -H 파일명과 함께 출력
  -i 대소문자를 구분하지 않음
  -n 검색한 문자가 속하는 행번호와 함께 출력
  -r 현재경로에서 하위경로까지 검색
  -v 검색하는 문자가 없는 행을 출력
  -w 패턴 표현식을 하나의 단어로 검색

grep 정규식
. 한글자
* 길이와 관계없는 문자열
^ 행의 첫 시작
$ 행의 마지막 위치
[] 한 문자길이 패턴
[^] 입력된 문자들의 여집합
wc : 특정 파일의 바이트 수나 검색하고자 하는 단어 수 및 행수를 알고자 할때 사용
  -c 바이트 크기 출력
  -m 문자 수를 출력
  -l 행수를 출력
  -L 가장 긴 문자만을 출력
sort : 파일을 내용을 정렬하는 명령어
  -k 지정한 필드를 기준으로 정렬
  -r 내림차순 정렬
  -f 모든 문자를 소문자로 식별
  -u 필드 내에서 중복된 값을 제거하여 유일한 값만 출력
cut : 텍스트 파일에서 특정 부분을 지정하여 출력할 수가 있는 명령어
  -b 특정 자리만 출력함
  -d 인자 문자열을 기준으로 해서 출력
  -f d옵션과 함께 사용되어서 구분된 필드를 출력
split : 파일을 나누고 싶을 때 사용
  -b 바이트 단위로 파일을 나눔
  -l 지정한 라인 수 만큼 파일을 나눔
  ex) split -b 1500k 파일명
diff : 두 개의 파일간의 차이점을 알 수 있음
shutdown : 리눅스 정지
  -r 재부팅
  -h shutdown 후 시스템 종료
  -c 진행중인 shutdown을 취소
  -k 경고메시지를 출력하고 실제 shutdown은 수행하지 않음
  -f fsck를 실행하지 않고 재부팅
  -t sec 지정한 시간에 재기동
  -v 상세 정보를 출력
reboot : 리눅스 다시 시작
  -n 연산은 중지하고 다시시작
  -f 강제로 다시시작
  -p 연산을 중지 시에 전원을 종료
  -q 오류가 없으면 다시시작하지 않음
  -v 상세정보 출력
netstat : 시스템과 연결된 모든 네트워크 연결을 확인
  -a 모든 소켓 정보를 확인
  -n 도메인 주소를 읽지 않고 숫자로 출력
  -p PID와 사용 중인 프로그램명을 출력
  -g 멀티캐스트 그룹 정보
ping : 네트워크 상태를 정보를 점검하기 위한 명령어(ICMP프로토콜을 사용하여 ICMP echo Request를 전송하고 ICMP echo reply가 되돌아오는 지 확인)
ping 210.220.163.82
PING 210.220.163.82 (210.220.163.82): 56 data bytes
64 bytes from 210.220.163.82: icmp_seq=0 ttl=248 time=9.240 ms
64 bytes from 210.220.163.82: icmp_seq=1 ttl=248 time=9.830 ms
nslookup : 도메인명에 대한 IP주소를 확인하기 위해 DNS에 질의를 실행함
$ nslookup www.naver.com
Server:        210.220.163.82
Address:    210.220.163.82#53

Non-authoritative answer:
www.naver.com    canonical name = www.naver.com.nheos.com.
Name:    www.naver.com.nheos.com
Address: 125.209.222.142
Name:    www.naver.com.nheos.com
Address: 125.209.222.141

halt : 리눅스 종료
  -d wtmp에 로그를 기록하지 않음
  -f 강제로 종료
  -n 종료할 때 동기화를 하지 않음
  -w 실제로 종료하지 않고 /var/log/wtmp에 로그를 기록

객체지향의 사실과 오해 - 인터페이스 부분 정리

객체지향의 사실과 오해 - 인터페이스
  • 인터페이스는 객체가 다른 객체와 협력하기 위한 접점
  • 일반적으로 인터페이스는 다음과 같은 세 가지 특징을 지님
1. 인터페이스의 사용법을 익히기만 하면 내부 구조나 동작방식을 몰라도 쉽게 대상을 조작하거나 의사를 전달할 수 있음
2. 인터페이스 자체는 변경하지 않고 단순히 내부 구성이나 작동방식만을 변경하는 것은 인터페이스 사용자에게 어떤 영향도 미치지 않는다
3. 대상이 변경되더라도 동일한 인터페이스르 제공하기만 하면 아무런 문제없이 상호작용을 할 수 있다
  • 객체가 다른 객체와 상호작용할 수 있는 유일한 방법은 '메시지 전송'
  • 책임은 객체가 메시지를 수신했을 때 수행해야 하는 객체의 행동이며, 실제로 객체의 공용 인터페이스를 구성하는 것은 객체가 외부로부터 수신할 수 있는 메시지의 목록
객체가 메시지를 수신했을 때 적절한 객체의 책임이 수행됨 -----> 메서드
  • 객체지향적인 사고방식을 이해하기 위해서는 세 가지 원칙이 중요
1. 좀 더 추상적인 인터페이스 : 지나치게 상세한 수준의 메시지를 보내는 것은 객체의 자율성을 저해함
2. 최소 인터페이스 : 외부에서 사용할 필요가 없는 인터페이스는 최대힌 노출하지 말라
(객체 내부를 수정하더라도 외부에 미치는 영향을 최소화할 수 있음)
3. 인터페이스와 구현간의 차이가 있다는 점을 인식
: 훌륭한 객체란 구현을 모른 채 인터페이스만 알면 쉽게 상호작용할 수 있는 객체
----> 객체 외부에 노출되는 인터페이스와 객체의 내부에 숨겨지는 구현을 분리해서 고려해야함
----> '인터페이스와 구현의 분리 원칙'
----> why? 객체의 모든 것이 외부에 공개돼 있다면 아무리 작은 부분을 수정하더라도 변경에 의한 파급효과가 객체 공동체의 구석구석까지 파고들 것임

'강조'
객체가 가져야 할 상태와 메서드 구현은 객체 내부에 속함. 이 부분을 수정하더라도 객체 외부에 영향을 미쳐서는 안됨
객체 외부에 영향을 미치는 변경은 객체의 공용 인터페이스를 수정할 때만
---> 캡슐화
  • 캡슐화: 객체의 자율성을 보존하기 위해 구현을 외부로부터 감추는 것
---> 객체의 상태와 행위를 캡슐화함으로써 협력적이고 자율적인 존재가 될 수 있음
  • 자율적인 객체? : 공용 인터페이스를 수정하지 않는 한 자신과 협력하는 외부 객체에 영향을 미치지 않고 내부의 구현을 '자유롭게' 수정할 수 있음
  • 결론: 객체가 자율적인 책임을 가지는 것이 중요하다
객체의 책임이 자율적일수록 협력이 이해하기 쉬워지고 유연하게 변경할 수 있게 된다

1. 자율적인 책임은 협력을 단순하게 만든다
---> 책임이 적절하게 추상화됨

2. 외부와 내부를 명확하게 분리
---> 요청하는 객체가 몰라도 되는 사적인 부분이 객체 내부로 캡슐화되면서 인터페이스와 구현이 분리됨

3. 내부적인 방법을 변경하더라도 외부에 영향을 미치지 않음
---> 책임이 자율적일 수록 변경에 의해 수정되야하는 범위가 좁아지고 명확(결홥도가 낮아짐)

4. 협력의 대상을 다양하게 선택할 수 있는 유연성을 제공
---> 설계가 유연해지고 재사용성이 높아짐

5. 객체의 역할을 이해햐기 쉬워짐
---> 객체의 응집도를 높은 상태로 유지가 쉬워짐

2018년 12월 16일 일요일

CI 실습해보기(AWS, Jenkins)

AWS의 EC2 를 이용하여 CI를 실습해보고자 한다.
단계는
1. AWS 인스턴스 신청
2. 서버 설정
3. GIT 연동하여 빌드 / 배포
로 나누어 진행했다.

1. AWS 인스턴스 신청

AWS는 1년 프리티어를 제공하고 있다. 이를 이용해서 무료서버를 체험해볼 수 있다.
프리티어를 사용하기 위해서는 마스터카드를 등록해야함.
가입 후 EC2 인스턴스를 생성한다.


나의 경우는 우분투를 선택하였다.

키페어를 생성 후 다운받아 인스턴스에 SSH 를 통해 접속할 수 있다.

잘 보관할 것
aws가 친절하게 인스턴스에 연결하는 방법을 알려준다. 키페어위치만 잘 입력하여 접속하자

yes를 누르면 다음과 같이 접속할 수 있는 것을 볼 수 있음

윈도우는 putty를 통해 접속할 수 있음

2. 서버 설정

- 자바 설치
sudo apt-get install openjdk-8-jdk
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package openjdk-8-jdk
해당 오류 발생(해당 패키지가 없는 듯하다..)
sudo add-apt-repository ppa:webupd8team/java
를 입력하고 다시 install 하니 설치가 되었다.
ubuntu@ip-:~$ sudo apt install openjdk-8-jdk
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  adwaita-icon-theme at-spi2-core ca-certificates-java dconf-gsettings-backend
  ...
0 upgraded, 148 newly installed, 0 to remove and 112 not upgraded.
Need to get 80.2 MB of archives.
After this operation, 443 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
자바설치완료!
ubuntu@ip~$ java -version
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-8u191-b12-0ubuntu0.18.04.1-b12)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)
- 톰캣 설치
톰캣과 톰캣어드민를 설치한다.
sudo apt-get install tomcat8

sudo apt-get install tomcat8-admin
어드민페이지에 접속할 수 있게 해당 xml을 수정한다.
sudo vi /etc/tomcat8/tomcat-users.xml
다음을 추가해준다
<role rolename="manager-gui"/>    
<role rolename="manager-script"/>  
<role rolename="manager-status"/>
<user username="admin" password="비번" roles="manager-gui,manager-script,manager-status"/>
manager 페이지는 
주소:8080/manager 입력하면 위에 입력한 username과 password를 입력하면 보여진다. 
해당 페이지에서 직접 war파일을 올려 배포할 수도 있다.

- DB설치
나의 경우에는 mysql을 설치하였음
설치 후 워크벤치로 서버에 설치된 DB에 접속하려하였지만, 계속 실패하였음
grant all privileges on *.* to root@'%' identified by '루트계정 비밀번호';
해당 명령어 입력 후 정상접속됨.. root 계정 권한문제?
- 젠킨스 설치
wget -q -O - https://pkg.jenkins.io/debian/jenkins-ci.org.key | sudo apt-key add -

echo deb https://pkg.jenkins.io/debian-stable binary/ | sudo tee /etc/apt/sources.list.d/jenkins.list

sudo apt-get update

sudo apt-get install jenkins
톰캣을 8080으로 써야하므로 젠킨스는 7070으로 포트 변경
sudo vim /etc/default/jenkins
HTTP_PORT 7070으로 변경
# port for HTTP connector (default 8080; disable with -1)
HTTP_PORT=7070
주소:7070 으로 접속하려하였지만, ERR_CONNECTION_TIMED_OUT 발생 7070을 못쓰나 하고 8080으로 다시 수정 후 접속하려하였지만, 또 발생
aws 방화벽 문제인 듯 하여 인스턴스 inbound 규칙 추가해줌

인바운드 아웃바운드 규칙란?
-인바운드 : 서버 내부로 들어오는 것 (클라이언트 -> 서버)
(ex 클라이언트가 업로드)
-아웃바운드 : 서버 외부로 송출 (서버 -> 클라이언트)
(ex 클라이언트가 다운로드)

- 젠킨스 설정
이제 http://주소:7070 을 들어가면 젠킨스 설정화면이 보인다.

첫 보안인증 화면은
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
의 패스워드를 쓰면 됨

잘 모르니 suggested 고고 ㅎㅎ;;

계정 생성하면 다음과 같은 화면보임! Jenkins 띄우기 성공! 

3. GIT 연동 / 빌드 / 배포

새로운 JOB을 만들어서
다음과 같이 Freestyle project 선택

소스코드관리 Git을 선택하고 띄울 프로젝트의 github저장소 URL 를 입력한다.

BUILD 
나의 경우에는 maven 빌드이므로 다음과 같이 설정하였음
프로젝트의 pom.xml 경로를 입력해준다. 

Jenkins를 통해 빌드만 하여 war만 만들어놓고 원하는 경로에 놓을 수 있지만, 젠킨스를 통해 빌드 후 배포까지 가능하다. 
빌드 조치 (배포) 빌드 후 조치 메뉴의 Deploy war/ear to a container 를 선택하여 다음과 같이 입력하였다.
서버에 깔린 톰캣 버전과 URL를 입력 후 매니저 페이지 계정과 비밀번호를 입력해주었음. 

경로만 제대로 입력/설정되어 있다면 다음과같이 빌드와 배포가 SUCCESS 가 된다.


젠킨스는 테스트, 알림, 다양한 플러그인 등의 다양한 기능을 제공하고있음.
이를 응용하여 더 해봐야할 듯 함!!!

=======================================================
ㅜㅜ....삽질을 너무 많이함 
1. mysql 계정권한문제 삽질 
2. 빌드 후 생성되는 war에 classes 하위가 없거나 src/main/webapp 폴더 안의 것들이 없었음
이것때문에 게속 삽질함... 그리고 젠킨스 빌드 시 서버가 급속도로 느려지면서 아무것도 못하는 경우 발생 인스턴스 재시작하면서 퍼블릭IP가 바뀌어서 매우 귀찮아졌었음.... ㅠ퓨

--> 느려지는 원인!!!
프리티어는 1기가 메모리를 제공하고있음.
근데 이 서버에 DB, tomcat, jenkins 까지 올려놓고 쓰니 당근 서버가 뻗을 수 밖에...

classes에 없는건 pom.xml 위치인 듯하고
(pom이 이상한 곳에 생성되었었는데 그걸로 빌드하니 class들이 모두 생성이 되지 않았음) 
webapp 없는건 경로문제인듯함 그래서 pom.xml에 warSourceDirectory  src/main/webapp 로 경로를 설정해주니 생김!
이 링크 참조하여 해결
이클립스에서도 war로 export하면 동일한 war가 생성되어 내 문제임을 알았다.
링크보고 이클립스 프로젝트 Properties - Deployment Assembly 에서
Source  와 Deploy Path 를 보고 
webapp가 이상한 것으로 잡혀있어서 배포 시 생성이 안된거였음...!
/src/main/webapp 가 없어서 추가하고 다시 export 하니 war가 제대로 생성되었음.

근데 이건 이클립스 프로젝트 설정 바꾸는건데 젠킨스는 git에서  땡겨서 빌드하는데 이 속성을 가져올 수 있을까?
 pom.xml

<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
        <warSourceDirectory>src/main/webapp</warSourceDirectory>
</configuration>
</plugin>


warSourceDirectory 에 원래 webapp만 있었는데 src/main 을 추가 후 git에 올리고 
다시 젠킨스로 빌드 후 배포하니 정상적으로 배포까지 완료됨... 
...와르소스디렉토리인데 왜 될까 ..? 

오! 여기 딱 나와있음...

WAR에 포함될 추가적인 파일들을 위한 디렉토리이다. 
이것은 너의 JSP파일들을 놓은 위치이다. 

메이븐 공부할 때 한번 읽어 볼 필요가 있을듯... 

https://maven.apache.org/plugins/maven-war-plugin/war-mojo.html

Required Parameters

NameTypeSinceDescription
<cacheFile>File2.1-alpha-1The file containing the webapp structure cache.
Default value is${project.build.directory}/war/work/webapp-cache.xml.
<outputDirectory>String-The directory for the generated WAR.
Default value is${project.build.directory}.
<warSourceDirectory>File-Single directory for extra files to include in the WAR. This is where you place your JSP files.
Default value is${basedir}/src/main/webapp.
<webappDirectory>File-The directory where the webapp is built.
Default value is${project.build.directory}/${project.build.finalName}.
<workDirectory>File-Directory to unpack dependent WARs into if needed.
Default value is${project.build.directory}/war/work.

todo 
1. git  push 인식하여 빌드하도록 설정하기 
2. 메이븐 공부하기 
(한번 읽어볼 것 
https://wikidocs.net/book/1910
)