[shell] -ksh: {파일명.sh}: not found 오류 문제

 

[상황]

 - 윈도우에서 스크립트 작성 후 linux로 옮겨 실행

 

아래와 같이 스크립트 파일 자체를 실행 할 수 없다고 오류 메시지가 출력

-ksh: {파일명.sh}: not found ~~

 

"쉘 스크립트 -ksh not found"로 오류 검색

 

[결론]

 - 윈도우는 텍스트 파일의 끝에서 CR-LF로 줄바꿈을 하고, 유닉스는 LF 문자로 줄바꿈을 한다.

 - 윈도우에서 작성한 쉘 스크립트가 리눅스로 옮겨 실행 시 스크립트 내에 "유닉스 개행문자"와 도스 개행문자"가 섞여 있을 때 문제 발생

 - 모든 문자열 끝에 '^M'이라는 문자는 개행문자가 깨진 흔적

 

[원인 파악 방법]

 

# 오류를 발생하는 파일을 vi 파라미터 -b를 추가하여 실행

vi -b {파일명}.sh

 - 오류가 발생했던 파일을 "vi -b {파일명}.sh"으로 실행하여 확인
(아래와 비슷한 문자열을 확인)

#!/bin/sh^M

function () {^M
    command^M
}^M

 

[원인]

 - 쉘 스크립트 파일 형식이 DOS 형식으로 인하여 CR(carriage return)이 달라서 생기는 경우로 파악

 

[해결책]

 1. vi 에디터에서 DOS 파일 타입을  Unix 파일 타입으로 세팅

# Unix Text로 변환

:set ff=unix

 2. vi에서 각 행의 끝에 있는 ^M 문자를, 모두 공백으로 바꾸기

# 각 행의 끝($)에 있는 ^M문자를 모두(g) 공백(//)으로 변환(%s)

:%s/^M$//g
# ^M쓰는 법

ctrl + v 키 > '^' ctrl + m > 'M'

 

 

'Basic > shell' 카테고리의 다른 글

[Shell] netstat  (0) 2020.02.12
[Shell] rsync  (0) 2019.09.03
[Shell] Exception Handling  (0) 2019.08.12
[Shell] 파일 찾기  (0) 2019.08.12
[shell] value too great for base (error token is "08")  (0) 2019.07.07

[Shell] rsync 사용법

- Rsync는 원격에 있는 파일디렉토리복사하고 동기화 하기 위해서 사용하는 툴

 

Rsync의 기능
 - 원격 시스템으로부터 파일을 효율적으로 복사하거나 동기화 가능
 - Linux, device, 파일의 소유자와 그룹 권한(Permissions)등 파일의 부가정보도 복사 가능
 - scp보다 빠름, rsync는 remote-update 프로토콜을 이용해서 차이가 있는 파일만 복사
(처음에는 모든 파일과 디렉토리를 복사 그 후부터는 차이가 있는 파일만 복사하기 때문에 더 빠르고 효율적)
 - 데이터를 압축해서 송/수신하기 때문에 더 적은 대역폭을 사용

 

Rsync의 동기화 알고리즘
1. 파일 전송 결정
    1) 파일의 크기와 수정시간(modification)을 비교하는 것으로 파일을 전송 할지 말지를 결정
(일반적으로 파일의 내용을 변경하면 크기와 수정시간이 변하지만 항상 그렇다고 단정할 수는 없다는 예외가 있다.)

    2) "--checksum" 의 옵션을 통해 비교 방법을 개선
(크기 / 시간을 이용한 비교 방법보다 안전하지만 더 느리고 더 많은 자원을 사용)

2. 전송할 파일 부분의 결정
    1) 파일을 고정 크기를 가지는 청크(chunk)로 나누어 checksum을 계산

    2) checksum을 서로 계산하여, 다를 경우 해당 부분의 청크만을 복사
(만일 파일의 앞 부분의 정보가 수정되어 정보가 밀릴 경우, 모든 chunk의 checksum이 어긋남)

    3) Rolling hash를 통해 위의 문제를 해결

 

Rsync의 사용법
# rsync [-v] [-q] [-a] [-r] [-b] [-u] [-l] [-p] [-o] [-g] [-D] [-t] [-n] [-e=Command] [–del|–delete] [-z] [–exclude] [–stats] [–progress] Source [[USER@]HOST:]DIST

 

Rsync의 주요 옵션

옵션

설명

-v

verbosity를 높이는 옵션으로 복사하는 과정을 더 자세하게 보여줌

-z

compress를 주는 옵션으로 파일을 복사할 때 압축해서 복사

-h

사람이 읽기 쉬운 형태로 복사 결과물들을 출력

-a 

(same as -riptgoD)

archive 모드로 -riptgoD 옵션을 적용한 것과 같음 (symlink, 권한, timestamp와 같은 속성을 그대로 복사)

-r

디렉토리를 복사 할 때 사용하는 옵션

-l

symlink는 symlink 형태로 복사하는 옵션

-p

파일과 디렉토리들의 권한을 유지하는 옵션

-t

수정시간을 유지하는 옵션

-g

그룹 속성을 유지하는 옵션

-o 소유자 속성을 유지하는 옵션

-D

(same as --devices --specials)

--devices --specials 옵션과 같음

--devices root 권한이 필요하며 Device  관련된 파일들을 복사해서 생성

--specials

name socket이나 fifo와 같은 특수한 파일들도 복사하는 옵션

 

 

Rsync 로컬에서 파일과 디렉토리 복사 및 동기화 

1. 원격 파일 복사 프로그램이지만 로컬 컴퓨터에서 사용도 가능

rsync -zvh {source} {destination}

2. 로컬 컴퓨터에서 디렉토리 복사 및 동기화

rsync -avzh {source} {destination}

 

 

Rsync 서버로부터 파일과 디렉토리를 복사 혹은 동기화

1. 로컬 서버에서 원격 서버로 디렉토리 복사

rsync -avz {domain}@{targetIP}:{targetPath} {localPath}

2. 원격 서버의 디렉토리를 로컬 서버로 복사

rsync -avzc {domain}@{targetIP}:{targetPath} {localPath}

 

Rsync SSH 사용
 - Rsync는 -e 옵션을 이용해서 ssh, rsh와 같은 remote shell 프로그램을 선택 가능
 - -e 옵션이 없다면 ssh 사용 (default)

 

Rsync server 모드
Rsyn 데몬  프로그램 설정
 - "--darmon" 옵션을 이용하여 서버 모드로 작동
 - xinetd를 이용해서 시스템 서비스로 등록

 

[ xinetd 패키지 설치 ]
1. /etc/xinetd.d/rsync 설정 파일 만들기
2. rsync 설정파일은 /etc/rsyncd.conf (설정파일이 없는 경우 직접 만들어야 함)
    1) 복사(동기화) 디렉토리로 /home/share를 선택
    2) 읽기/쓰기 모두 가능 설정
    3) 디렉토리에 대한 소유자는 nobody.nogroup, /home/share 소유자를 nobody.nogroup로 변경
    4) 접속 허용 유저로 user을 추가
    5) auth users에 대한 설정파일은 /etc/rsyncd.secrets에 저장
    * /etc/rsyncd.serets 파일에 접속유저이름과 패스워드를 지정할 수 있다. (패스워드는 plain/text)
3. 읽기 테스트
4. 쓰기 테스트

 

Rsync 데이터 복사 진행 상황 확인
 - "--progesss" 옵션 (진행정도를 화면에 출력)

 

Rsync Include exclude 옵션

1. include

2. exclude

 - 복사할 파일을 제외

# data 디렉토리를 복사에서 제외

rsync -avz --exclude 'data' {domain}@{targetIP}:{targetPath} {localPath}
# (*)를 사용하여 .bak 확장자를 포함하는 파일만 제외

rsync -avz --exclude '*.bak' {domain}@{targetIP}:{targetPath} {localPath}

 

Rsync delete 옵션
# "--delete" 옵션을 사용하여 삭제 후 복사

rsync -avz --delete {domain}@{targetIP}:{targetPath} {localPath}

 

Rsync 전송할 파일의 최대 크기 정하기
# "--max-size" 옵션을 이용해서 전송할 파일의 최대 크기를 정함

rsync -avz --max-size='10k' {doamin}@{targetIP}:{targetPath} {localPath}

 

Rsync 성공적으로 전송 후 원본파일 지우기
#"--remove-source-files"이용하여 전송이 끝난 후 원본 파일 삭제

rsync --remove-source-files -zvh {file} {경로}

 

Rsync Bandwidth 제한 설정
# "--bwlimit" 옵션을 이용하여 파일전송에 사용할 네트워크 대역폭을 제한
# 인터넷 서비스중인 서버에서, 다른 서비스에 영향을 주지 않는 범위내에서 파일 복사를 원할 경우 유용하게 사용

rsync --bwlimit=100 -avzhe ssh {localPath} {domain}@{targetIP}:{targetPath}

 

[참고]

https://www.tecmint.com/rsync-local-remote-file-synchronization-commands/

 

'Basic > shell' 카테고리의 다른 글

[Shell] netstat  (0) 2020.02.12
[Shell] -ksh {파일명}.sh: not found  (0) 2019.09.05
[Shell] Exception Handling  (0) 2019.08.12
[Shell] 파일 찾기  (0) 2019.08.12
[shell] value too great for base (error token is "08")  (0) 2019.07.07

쉘 작업 하다가 쉘 명령어가 실행이 안되었을 경우

어떻게 확인해야 하나 고민하다가 java에서 처럼 예외처리하는 방법이 있는지 찾아봄

 

 * 실행 명령어를 조건문에 넣어서 1과 0으로 판단 (0: TRUE, 1: FALSE)

"실행 명령어" && echo "실행됨" || echo "실행안됨!"

위 명령어의 처리 순서

 

"실행 명령어" 실행 결과가 정상 일 경우 `&& echo "실행됨"`이 실행 되어 결과적으로 "실행됨"이 출력

"실행 명령어" 실행 결과가 오류 발생 시 `|| echo "실행안됨!"`이 실행 되어 결과적으로 "실행안됨!"이 출력

 

 * 다중 명령어 수행 시

{

	"실행 명령어1" &&
	"실행 명령어2" &&
	echo "실행 명령어 수행 완료 로그"
    
} || {

	echo "실행 명령어 수행 실패 로그"
	"실행 명령어 수행 실패 시 수행될 명령어"
	exit 1
    
}

'Basic > shell' 카테고리의 다른 글

[Shell] netstat  (0) 2020.02.12
[Shell] -ksh {파일명}.sh: not found  (0) 2019.09.05
[Shell] rsync  (0) 2019.09.03
[Shell] 파일 찾기  (0) 2019.08.12
[shell] value too great for base (error token is "08")  (0) 2019.07.07
# 현재 폴더 내에 파일 검색 (하위폴더 포함)
find .

 

# 현 폴더 이하 생성된지 7일 이하 파일 찾기
find -type f -ctime -7
# 현 폴더 이하 7일 이내로 수정된 파일 찾기
find -type f -mtime -7

 

# 현 폴더 내에 파일 총 개수 찾기
find "path" -type f | wc -l

 

'Basic > shell' 카테고리의 다른 글

[Shell] netstat  (0) 2020.02.12
[Shell] -ksh {파일명}.sh: not found  (0) 2019.09.05
[Shell] rsync  (0) 2019.09.03
[Shell] Exception Handling  (0) 2019.08.12
[shell] value too great for base (error token is "08")  (0) 2019.07.07

 * 오류 해결하기

 

변수가 08일 때 수식으로 비교하려 할 때 발생

쉘 스크립트는 특별한 접두사나 표기법이 없다면 숫자를 10진수로 해석한다.
만약에 숫자 앞에 0이 있다면 8진수이고, 0x이 있으면 16진수
#이 들어간 숫자는 진법#숫자로 계산된다.

 

# 10진수
23 > 23
45 > 45

# 8진수 ('0'다음에 나오는 숫자)
071  > 8 (10진수로 표현)

# 16진수 ('0x'나 '0X' 다음에 나오는 숫자)
0x7a > ? (10진수로 표현)

* 날짜로 만들어지는 폴더 경로를 SFTP 명령어로 작성 하고 싶다.

 

이를테면 SFTP 로 접근해서 해당 경로에 파일을 지운다던가

 

이때 폴더가 날짜값으로 만들어지는 이유로 반복문을 돌리는데 숫자 2자리 수 이전 값에서는 01, 02, ... 09와 같은 포맷을 만들기 위해서는 몇가지 작업이 필요하더라

 


 * 한 자리 수 숫자 앞에 0을 붙이는 방법

 

`seq [option] [first_number] [increment] [last_number]`

`seq [option] [first_number] [last_number]`

`seq [option] [last_number]`

 

[option]

-f 포맷방식 "02g", "03g"
-w 마지막 숫자(last_number) 자릿수에 맞게 0을 채움 seq -w 1 10
-s 숫자 사이에 특정 구분자를 추가 seq -s "/t" -w 1 5

 


 * 내가 활용한 방법

`seq -f "02g" 시작 끝`

 

for time in `seq -f "02g" $START $END` ; do

	shtp -i $SSHKEY "사용자계정@호스트" << EOF
    	rm /경로/$time/*
    	quit
        EOF
    
done

 

'Basic > shell' 카테고리의 다른 글

[Shell] netstat  (0) 2020.02.12
[Shell] -ksh {파일명}.sh: not found  (0) 2019.09.05
[Shell] rsync  (0) 2019.09.03
[Shell] Exception Handling  (0) 2019.08.12
[Shell] 파일 찾기  (0) 2019.08.12

[작업내용]

...더보기

파일을 읽어서 DB에 넣을 때 특정 컬럼의 값이 Not Null 일 때 다른 컬럼의 값에 특정 문자열을 추가 하는 작업

ex) A 컬럼의 값이 존재 -> B 컬럼에 "이득" 문자열 추가 삽입

[문제]

...더보기

Not Null 값으로 보이는 컬럼 값을 DB가 값이 있는 것으로 판단하여 특정 문자열을 추가하는  현상

 

[원인 파악]

...더보기

해당 파일에서  특정 컬럼에 들어가는 내용을 모두 읽어 String의 값에 length를 확인

 * 문제의 값의 length는 1로 출력됨

 * 눈으로 판단하기에는 \t으로 보이는 값이 출력되고 있음

 * trim()으로 처리 하려고 했으나 trim() 또는 replaceAll(" ", "")로 처리가 안됨

 

문자열이 특수한 값인지 파악하기 위하여 str.chatAt(0)의 값을 형변환 한 뒤 출력

 * 출력된 값은 12288

 * 12288이란 값은 cjk 문자셋에서 나타나는 IDEOGRAPHIC SPACE라 불리는 유니코드 \u3000 또는 HTML 표현으로는 &#12288; 이라는 문자로 폰트 지원이 없으면 눈에 보이지 않는 코드로 존재

 

[해결 방법]

...더보기

현 상황에서 해결한 방법은 몇 가지 가정을 기반으로 작업하였다.

 * 현 상황에서는 특수 문자가 컬럼 내에 하나만 존재한다.

 * 문자열 사이에는 존재하지 않는다.

 

* 이 작업을 했을 경우 예상되는 이슈

 - 특정 파일의 값을 개발자가 임의로 수정하는 경우이기 때문에 모든 값을 알지 못하면 의도하지 않은 값이 수정될 수 있다.

 

String whatTheString = " ";
System.out.println("[LOG] [SpecialWord:" + whatTheString.length() + "]");

/* trim() 처리 시도 */
System.out.println("[LOG] [Trim(): " + whatTheString.trim() + "]["+ whatTheString.trim().length() + "]");

/* 문자열 확인 (12288의 값이 출력) */
int whatInt = whatTheString.charAt(0);
System.out.println("[LOG] [charAt(0):" +  whatInt + "]");

/* 모든 문자열의 공백을 제거 */
String replaceAllStr = whatTheString.replaceAll("\\p{Z}", "");
System.out.println("[LOG] [replaceAll:" + replaceAllStr + "]");

/* 문자열 처음과 끝에 내용만 없애기 */
String replaceStr = whatTheString.replaceAll("(^\\p{Z}+|\\p{Z}+$)", "");
System.out.println("[LOG] [replaceAll(regExp):" + replaceStr + "][" + replaceStr.length() + "]");

 

[Handlebars] 사용하기

 - 이 문서는 http://handlebarsjs.com/를 참조하여 작성했습니다.


[Handlebars 사용할 경우]



[프로젝트에 적용해보기]

See the Pen ZVMrVL by seokrae (@seokrae) on CodePen.



[Java Server Pages] JSP 파일 업로드 & 다운로드 

 - GitHub




[내용 설명]


 1. 서블릿 3 파일 업로드

   1) MultipartConfig

· fileSizeThreshold: 파일이 디스크에 쓰여지는 사이즈를 지정할 수 있다. 크기 값은 바이트 단위(1024 * 1024 * 10 = 10MB)

· location: 파일이 기본적으로 저장되는 디렉토리, 기본값은 ""

· maxFileSize: 파일을 업로드할 수 있는 최대 크기, 값은 바이트 단위

· maxRequestSize: multipart/form-data 요청에 허용되는 최대 크기, 기본값은 무제한을 의미하는 -1L


   2) Part Interface

· Part 인터페이스는 miltipart/form-data POST 요청으로 수신받은 from 아이템이나 하나의 Part를 나타낸다.

· 몇가지 중요한 메서드는 getInputStream(), write(String fileName)으로 읽고 쓰는데 사용한다.


   3) HttpSerlvetRequest 변경사항

· HttpServletRequest에 getParts()메서드를 사용하여 multipart/form-data 방식으로 가져오는 모든 데이터를 가져올 수 있다.

· getPart(String partName)을 통해 필요한 내용만을 가져올 수도 있다.


[소스 코드]


1. JSP 파일 업로드 폼



2. Java 파일 업로드 기능



3. JSP 파일 업로드 결과 값 출력



4. Java 파일 다운로드 기능



'Basic > Jsp' 카테고리의 다른 글

[JSP 2.3 웹 프로그래밍 기초부터 중급까지] 정리  (2) 2017.10.21

+ Recent posts