bash script (backup)2021. 9. 24. 16:50

 

반달가면 이글루에서 백업 - http://bahndal.egloos.com/524038

 

특정 디렉토리에서 용량을 가장 많이 차지하고 있는 파일을 찾아야 할 때가 있다. 일일이 용량을 눈으로 확인해도 되지만 파일 수가 아주 많을 때는 좀 더 우아한(?) 방법을 찾아야 한다.

우선 정렬을 위한 sort 명령을 생각해 보자.

# 8 에서 11까지 출력하고 정렬
seq 8 11 | sort
10
11
8
9

 

seq 명령을 이용해서 8에서 11까지 출력한 후 이것을 sort 명령으로 정렬하면 출력한 수자를 문자로 간주하고 정렬하므로 위의 예시와 같은 결과가 나온다. 수자를 수자로 인식하기 위해서는 -g 옵션을 사용하면 된다.

seq 8 11 | sort -g
8
9
10
11

자, 이제 가장 큰 수부터 출력하도록 정렬 순서를 반대로 한다. -r 옵션을 사용하자.

seq 8 11 | sort -g -r
11
10
9
8

큰 파일들을 찾기 위한 준비가 끝났다. ls -l 명령으로 디렉토리에 있는 파일명과 크기를 같이 출력한 후에 awk 명령으로 파일 크기와 파일명만 골라내고, 이 결과값을 sort 명령으로 정렬한다.

# ~/my_dir 디렉토리의 파일 용량 TOP10 출력
ls -l ~/my_dir | grep "^\-" | awk '{print $5 "\t" $9}' | sort -g -r | head -10

 

ls -l 명령의 출력에서 디렉토리나 심볼릭 링크를 제외하고 파일만 골라내기 위해 '-' 부호로 시작하는 행만 선별하고(grep 명령)

파일 용량(5번째 항목)과 파일명(9번째 항목)만 골라서 탭(tab)을 구분자로 해서 출력한 후(awk 명령)

가장 용량이 큰 항목부터 출력하도록 정렬(sort 명령), 여기서 맨 처음 10개 행만 표시(head 명령)

용량을 많이 차지하고 있는 디렉토리를 찾고 싶다면 du 명령 이용하면 된다. 아래의 예시를 보자.

# ~/my_dir 디렉토리 하위에 있는 디렉토리 용량 TOP10 출력
du ~/my_dir | sort -g -r | head -10

 

 

Posted by 반달가면

댓글을 달아 주세요

bash script (backup)2021. 6. 28. 12:58

 

반달가면 이글루에서 백업 - http://bahndal.egloos.com/517484

 

특정한 파일이 현재 전송되고 있는지 판단하기 위한 방법이다. 다수의 파일을 ftp로 받고 있거나 NFS를 통해서 복사하는 상황에서 이 파일들에 대한 작업을 해야 하는데, 전송중인 파일과 전송완료된 파일을 구분하기 위한 것.

파일이 마지막으로 수정된 시간과 현재 시간과의 차이를 확인하여 정해 둔 기준과 비교하면 되겠다. 파일이 마지막으로 수정된 시간은 stat 명령으로 확인한다. 아래의 예시를 보자.

# 마지막으로 수정된 시간, 1970.1.1 0시부터 경과한 시간을 초(second)로 표시

stat -c %Y my_file.txt

 

-c 옵션으로 출력할 항목을 지정하는데, %Y 항목을 사용. stat 명령을 이용하면 그 외에도 파일에 대한 다양한 정보를 확인할 수 있다. 자세한 내용은 man 페이지를 참고하자.

 

man stat

 

현재 시간은 date 명령을 사용하여 출력. 앞의 stat 명령과 동일한 형태로 출력할 수 있다.

 

# 현재 시간, 1970.1.1 0시부터 경과한 시간을 초(second)로 표시

date "+%s"

 

대상 파일이 현재 전송중이라면, 마지막으로 수정된 시간과 현재 시간과의 차이가 근소해야 한다. 별 문제가 없다면 1초 이하일 것이다. 만약 부하가 많이 걸리거나 네트워크 상태가 별로 좋지 않아서 전송이 지연되고 있다면 좀 더 차이가 날 수도 있을 것이다.

 

대강 시간차가 10초 이하면 현재 전송중이라고 판단하고 그 이상이라면 전송이 끝났다고 판단하는 경우의 예시를 보자.

 

# 대상 파일: my_file.txt

target_file=my_file.txt

# 시간차 기준: 10초

diff_limit=10

# 마지막으로 수정한 시간

mod_time=`stat -c %Y $target_file`

# 현재 시간

cur_time=`date "+%s"`

# 시간 차이 계산

diff=`echo "$cur_time - $mod_time" | bc`

# 시간차가 $diff_limit 이하면 전송중이라고 판단

if [ $diff -le $diff_limit ]

  then echo "$target_file: 전송중입니다."

  else echo "$target_file: 전송완료되었습니다."

fi

 

Posted by 반달가면

댓글을 달아 주세요

bash script (backup)2021. 6. 8. 14:20

 

반달가면 이글루에서 백업 - http://bahndal.egloos.com/517067

 

특정 파일 또는 디렉토리가 존재하는지 확인하는 방법이다. 스크립트의 인자(argument)로 파일이나 디렉토리를 입력받았을 경우 인자의 유효성을 확인할 때 요긴하게 사용 가능.

우선 파일의 존재 여부를 확인해 보자. if 조건문에서 test 명령의 -e 옵션을 사용하면 된다. 아래의 예시를 참고하자.

 

file_name="my_file.txt"

# 파일이 있을 경우 메세지 출력

if test -e $file_name

then echo "$file_name 파일을 찾았습니다."

fi

 

# 파일이 없을 경우 메세지 출력(! 사용)

if ! test -e $file_name

then echo "$file_name 파일이 없습니다."

fi

 

디렉토리의 존재 여부는 -d 옵션을 사용하면 된다.

 

dir_name="/var/log/"

# 디렉토리가 있을 경우 메세지 출력

if test -d $dir_name

then echo "$dir_name 디렉토리를 찾았습니다."

fi

 

test 명령은 대괄호([ ])로 대체해서 쓸 수도 있다. 바로 위의 if 조건문 예시를 아래과 같이 써도 된다.

 

if [ -d $dir_name ]

then echo "$dir_name 디렉토리를 찾았습니다."

fi

 

대괄호를 사용할 때는 띄어쓰기에 주의하자. 대괄호 안의 표현과 대괄호 사이에 반드시 공백이 한칸 들어가야 한다.

Posted by 반달가면

댓글을 달아 주세요

bash script (backup)2021. 3. 3. 15:37

 

반달가면 이글루에서 백업 - bahndal.egloos.com/508427

 

date 명령을 이용해서 파일을 마지막으로 수정한 날짜와 시간을 확인할 수 있다. -r 옵션을 사용한다. 아래의 예시를 보자.

 

date -r my_file.txt

2014. 07. 03. (목) 16:34:33 KST

 

원하는 항목만 골라내는 등 표시 형식을 바꿀 수도 있다. 아래의 예시를 보자.

 

# 연도만 구하기

date -r my_file.txt "+%Y"

2014

 

# 연도 및 날짜

date -r my_file.txt "+%Y%m%d"

20140703

 

Posted by 반달가면

댓글을 달아 주세요

bash script (backup)2021. 1. 6. 13:15

 

반달가면 이글루에서 백업 - bahndal.egloos.com/476203

 

무작위로 이름이 정해지고 해당 사용자에게만 접근권한이 있는 임시 파일 또는 임시 디렉토리를 만들고 싶다면 mktemp 명령을 활용하자. 일단 아래의 예시를 보자.

 

mktemp myfile_XXXX.tmp

myfile_iX9v.tmp (파일이 생성된 후, 이름이 출력된다)

 

현재 디렉토리에서 "myfile_"로 시작되고 바로 뒤 4개 글자가 무작위로 정해지면서 확장자가 .tmp인 파일을 만든 후 파일 이름이 화면에 출력되었다. 이름에서 'X'라고 된 부분이 무작위로 바뀌며, 최소한 3개 이상의 'X'를 지정해야 한다.

 

임시 디렉토리를 만들고 싶다면 -d 옵션을 이용.

 

mktemp -d mydir_XXXX

mydir_jKuI (디렉토리가 생성된 후, 이름이 출력된다)

 

그냥 touch 또는 mkdir 명령을 사용해도 될 것 같은데 굳이 mktemp 명령이 필요한 이유는 무엇일까?

 

사실 홈 디렉토리에서 임시 파일을 만든다면 mktemp 명령을 굳이 쓰지 않아도 될 것 같다. 하지만 메모리 영역(RAM)에 연결된 /dev/shm 디렉토리에 임시 파일을 만들고 싶다면 되도록 mktemp 명령을 사용하는 것이 안전하다. /dev/shm 디렉토리의 권한이 777(rwxrwxrws)로 설정되어 있어 모든 사용자가 접근할 수 있기 때문이다.

 

반복적인 읽기/쓰기가 이루어지는 경우에 임시 파일을 일종의 램디스크인 /dev/shm 디렉토리에 만들면 디스크보다 훨씬 빠르다는 장점이 있다. 접근권한의 문제는 mktemp 명령으로 해결하면 된다. mktemp 명령으로 생성된 임시 파일의 권한은 600(rw-------), 임시 디렉토리의 권한은 700(rwx------)이다. 즉, 소유자만 접근 가능.

 

mktemp /dev/shm/myfile_XXXX.tmp

/dev/shm/myfile_BW66.tmp (파일 생성후 파일명 출력)

 

스크립트에서는 아래의 예시를 참고해서 활용해 보자. mktemp 명령의 출력 결과를 변수에 할당해서 사용하면 되겠다.

 

# 임시 디렉토리를 만들어 이름을 tmp_dir 변수에 할당

tmp_dir=`mktemp -d /dev/shm/mydir_XXXX`

# 임시 디렉토리 안에 임시 파일을 만들고 이름을 tmp_file 변수에 할당

tmp_file=`mktemp $tmp_dir/myfile_XXXX.tmp`

echo "temp file created: $tmp_file"

# 이제 임시 파일을 사용하면 된다. 문자열 abcde를 임시 파일에 저장

echo "abcde" > $tmp_file

...

# 임시 파일 삭제

rm $tmp_file

# 임시 디렉토리 삭제

rm -r $tmp_dir

 

 

Posted by 반달가면

댓글을 달아 주세요

bash script (backup)2020. 12. 23. 13:21

 

반달가면 이글루에서 백업 - bahndal.egloos.com/468623

 

우선, 파일 또는 디렉토리 하나의 이름을 바꾸고 싶으면 mv 명령을 이용하자. 아래의 예시를 보면 되겠다.

 

# 이름 변경: my_text.txt -> old_text.txt

mv my_text.txt old_text.txt

 

여러개의 파일이나 디렉토리에 대해 한꺼번에 이름을 바꾸고 싶다면 rename 명령을 이용하면 되겠다. 아래의 예시는 확장자가 txt인 파일에서 abc를 def로 바꾸는 경우이다.

 

# 확장자가 txt인 파일에서 abc를 def로 변경

rename 's/abc/def/' *.txt

 

만약 파일명이 abcd.txt라면 defd.txt로 바뀌게 된다. 만약 파일명이 abc_abc.txt라면 어떻게 될까? 처음 abc만 def로 바뀐다. 즉, def_abc.txt로 바뀐다. 같은 문자열이 반복될 경우 모두 바꾸고 싶다면, 즉 위의 예시에서 abc_abc.txt를 def_def.txt로 바꾸고 싶다면 아래와 같이 g 옵션을 쓰면 된다.

 

rename 's/abc/def/g' *.txt

 

-n 옵션을 사용하면 실제로 이름을 바꾸지는 않고, 어느 파일/디렉토리가 어떤 이름으로 바뀔 것인지만 화면에 출력해 준다. 실제로 바꾸면서 결과를 출력하고 싶으면 -v 옵션을 사용하자.

 

# 이름이 바뀔 파일과 바뀌게 될 결과만 출력(실제로 바꾸진 않음)

rename -n 's/abc/def/' *.txt

 

# 실제로 이름을 바꾸고, 바뀐 결과를 화면에 출력

rename -v 's/abc/def/' *.txt

 

find 명령과 xargs 명령을 조합해서 사용해도 편리하다. (find와 xargs 명령은 이전 게시물을 참고하자)

 

# abc가 포함된 디렉토리(-type d)를 찾아서 def로 변경

find -type d | grep abc | xargs rename 's/abc/def/'

 

Posted by 반달가면

댓글을 달아 주세요

bash script (backup)2020. 12. 2. 15:28

 

반달가면 이글루에서 백업 - bahndal.egloos.com/465115

 

조건에 맞는 파일을 찾아 특정 디렉토리로 복사를 하고 싶을 경우, find와 cp 명령을 xargs 명령으로 연결하면 되겠다.

파일을 찾기 위한 find 명령에 대한 내용은 이전 게시물을 참고하자.

 

우선 홈디렉토리(~/)에서 확장자가 txt인 파일을 찾는 예시를 보자.

 

find ~/ -type f | grep "\.txt$"

 

자, 이 결과를 가져와서 cp 명령을 실행해야 한다. 앞에 실행한 명령의 결과를 뒤에 실행할 명령의 인자(argument)로 넘겨주는 xargs 명령을 이용하는데, 한가지 유의할 점이 있다. 아래의 예시를 보자.

# txt 파일을 찾아 ~/Documents 디렉토리로 복사 (잘못된 시도)

find ~/ -type f | grep "\.txt$" | xargs cp ~/Documents

# 실패!

 

위와 같이 하면 제대로 복사가 되지 않는다. cp 명령에서 복사하려는 목적지 디렉토리와 앞의 find 명령에서 넘어온 파일 목록이 혼동되지 않도록 반드시 -t 옵션을 사용해야 한다. 제대로 된 예시는 아래와 같다.

 

# txt 파일을 찾아 ~/Documents 디렉토리로 복사(성공)

find ~/ -type f | grep "\.txt$" | xargs cp -t ~/Documents

 

Posted by 반달가면

댓글을 달아 주세요

bash script (backup)2020. 11. 26. 14:05

 

반달가면 이글루에서 백업 - bahndal.egloos.com/456590

 

용량이 큰 텍스트 또는 바이너리 파일을 분할하거나 재조립할 필요가 있을 때, split 명령과 cat 명령을 활용하면 되겠다. 

split 명령의 형식은 아래와 같다. 

split [options] file prefix

 

우선 텍스트 파일을 분할해 보자. 예를 들어 myfile.txt 파일을 100행 단위로 잘게 나누어 myfile_part로 시작되는 파일명으로 저장하는 경우다. 터미널창에서 아래와 같이 입력해 보자. -l 옵션으로 나눌 행(line) 단위를 지정하면 된다.

 

split -l 100 myfile.txt myfile_part

 

나누어진 결과는 myfile_partaa, myfile_partab,... 이런 식으로 저장된다.

 

기본 순서가 aa, ab, ac 이런식으로 정해지는데 알파벳이 싫으면 수자를 이용해서 00, 01, 02 이런 식으로 순서를 표시할 수도 있다. -d 옵션을 사용.

 

split -d -l 100 myfile.txt myfile_part

 

결과 파일은 myfile_part00, myfile_part01,... 이런 식이 될 것이다.

 

만약 번호 자리수를 늘리려면 -a 옵션을 사용하자. -a 3 이렇게 하면 세자리로 늘어난다.

 

split -d -a 3 -l 100 myfile.txt myfile_part

 

결과 파일은 myfile_part000, myfile_part001,... 이런 식이다.

 

바이너리 파일은 행 단위가 아니라 바이트(byte) 단위로 분할한다. -l 옵션 대신 -b 옵션을 사용하면 되겠다. 크기 설정에 킬로(k), 메가(m), 기가(g) 등 단위도 사용 가능.

 

myfile.bin 파일을 100kb 단위로 분할하는 예시는 아래와 같다.

 

split -d -a 3 -b 100k myfile.bin myfile_part

 

재조립 요령은 텍스트/바이너리 상관 없이 동일하게 cat 명령을 사용하면 된다. 앞의 예시에서 분할된 파일을 재조립하려면 터미널창에서 아래와 같이 입력한다.

 

cat myfile_part* > myfile_merged

 

마음의 평화를 위해 파일 순서를 명시적으로 맞추고 싶다면 아래와 같이 sort 명령을 같이 사용할 수도 있긴 한데, 굳이 이렇게 하지 않아도 큰 문제 없이 잘 합쳐지는 것 같다.

 

ls myfile_part* | sort | xargs cat > myfile_merged

 

 

Posted by 반달가면

댓글을 달아 주세요

bash script (backup)2020. 10. 23. 14:33

 

반달가면 이글루에서 백업 - bahndal.egloos.com/422524

 

리눅스에서 파일을 암호화하고 싶다면 openssl을 활용할 수 있다. 터미널창에서 아래와 같이 입력한다.

 

openssl aes-256-cbc -in my_file.txt -out my_file.enc

 

my_file.txt 파일을 미국의 암호화 표준인 AES로 암호화하여 my_file.enc라는 이름으로 저장하는 예이다. 위와 같이 실행하면 암호를 입력하라는 메시지가 나오는데, 암호를 정해서 넣어주면 되겠다. (대소문자, 수자, 특수기호 등을 섞어서 최소 15자 이상이 되도록 정하는 것을 추천)

 

암호화하면 암호화된 파일이 새로 생기고 원본 파일도 그대로 있으므로 원본 파일은 rm 명령으로 지워주자.

 

rm my_file.txt

 

아래와 같이 -d 옵션을 주면 원래 파일로 복원할 수 있다. 암호화된 my_file.enc를 복원하여 my_file.txt로 저장하는 예이다.

 

openssl aes-256-cbc -d -in my_file.enc -out my_file.txt

 

마찬가지로 복원을 위해서는 암호를 입력해 주면 된다. shell script에서 파일 암호화를 사용할 때, 암호를 특정 규칙에 의해 자동으로 생성하거나 한번 암호를 입력 받아서 여러개의 파일을 작업해야 할 상황이 있다면 아래와 같은 방식이 유용하다.

 

password_str="my_password"

echo -n "$password_str" | openssl aes-256-cbc -in my_file.txt -out my_file.enc -pass stdin

 

위의 예는 password_str 변수에 저장된 암호를 echo 명령으로 출력하고 openssl에서는 -pass stdin 옵션을 추가해서 암호가 자동으로 입력되도록 하는 것이다. 엔터가 포함되지 않도록 echo 명령에 -n 옵션을 사용했다. 암호는 파이프(|)에 의해 openssl 명령의 입력으로 넘어가기 때문에 암호가 실제로 터미널창 화면에 출력되지는 않는다.

 

복원은 앞에서 예시한 바와 같이 -d 옵션을 사용하면 된다.

 

echo -n "$password_str" | openssl aes-256-cbc -d -in my_file.enc -out my_file.txt -pass stdin

 

암호를 자동으로 입력하는 다른 방법으로 아래의 예시를 보자.

 

openssl aes-256-cbc -in my_file.txt -out my_file.enc -pass pass:my_password

 

위와 같은 방식은 비추천이다. 암호화가 진행되고 있는 도중에 ps 명령으로 프로세스 목록을 보면 암호가 그대로 드러나기 때문이다. echo 명령과 조합하는 방식이 더 낫다.

 

 

Posted by 반달가면

댓글을 달아 주세요

bash script (backup)2020. 10. 16. 11:43

 

반달가면 이글루에서 백업 - bahndal.egloos.com/385339

 

for문을 이용해서 특정 디렉토리에 있는 특정 파일에 대해 일률적으로 반복 작업을 할 수 있다.

홈 디렉토리에 있는 txt 파일을 골라 내용을 화면에 표시하는 예시를 보자.

 

for file_name in ~/*.txt
do
echo "[ opening $file_name ]"
cat $file_name
echo " "
done

 

자, 그럼 앞에 올렸던 ftp 자동접속 방법을 합쳐서 홈 디렉토리의 txt파일만 골라 특정 서버에 올리는 작업도 쉽게 해 볼 수 있겠다.

 

for file_name in ~/*.txt
do
echo "[ uploading $file_name ]"
ftp -n 192.168.0.10 << SCRIPT
  user john my_password
  binary
  put $file_name
  quit
SCRIPT
done

 

 

Posted by 반달가면

댓글을 달아 주세요