bash script (backup)2021. 1. 14. 17:21

 

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

 

sleep 명령은 초 단위로만 쉴 수 있다고 생각하고 있었는데, 이제 보니 1초 미만으로 정할 수 있구나. (sleep 명령의 man 페이지를 보니 소수점도 사용할 수 있다고 나와있다.)

아래의 예시를 참조하자.

# 0.1초 쉬기
sleep 0.1

# 1시간 30분 30초동안 쉬기
sleep 1h 30m 30s
# 1.5시간 동안 쉬기
sleep 1.5h

 

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 반달가면

댓글을 달아 주세요

리눅스 (backup)2021. 1. 6. 10:58

 

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

 

리눅스에서 df 명령으로 디스크의 빈 공간을 확인해 보면 /dev/shm 디렉토리가 있는데, 파일시스템 형식은 tmpfs이고 크기는 램(RAM) 용량의 반 정도 될 것이다.
 
이 디렉토리는 공유 메모리(shared memory)라고 해서 일종의 램디스크인데, RAM 용량의 반을 당장에 실제로 점유하고 있는 것은 아니고 사용하는 만큼만 용량을 소모한다. 그러므로 RAM 용량이 반이나 날아갔다고 오해하면서 걱정할 필요는 없다.

자주 읽기/쓰기를 하는 임시 파일을 사용해야 할 경우에 RAM 용량이 충분하다면 이 디렉토리가 상당히 요긴하다.

다만, 한가지 주의할 점은 /dev/shm의 접근 권한이다. 모든 사용자가 읽고 쓸 수 있으므로, 만약 이 디렉토리를 사용하고 싶다면 하위에 자신만 접근할 수 있는 권한으로 디렉토리를 하나 만들어서 사용하자.

cd /dev/shm
mkdir my_tmp_dir
chmod 700 my_tmp_dir  (자신만 접근할 수 있도록 권한 설정)

참고로, 만약 다른 프로그램들이 RAM을 이미 많이 점유하고 있는 상태에서 /dev/shm 디렉토리를 사용하다가 사용량이 RAM 용량을 초과하게 되면 그 때는 스왑(swap) 영역으로 넘어간다.

 

Posted by 반달가면

댓글을 달아 주세요

리눅스 (backup)2021. 1. 6. 10:53

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

 

디렉토리 점유 용량을 확인하는 명령인 du와 상호보완적으로 쓰게 되는 명령이 디스크/파일시스템의 빈 공간을 확인하기 위한 df 명령이다. 터미널 창에서 아래와 같이 입력해 보자. 

df

표시되는 항목은 파일시스템(Filesystem), 디스크 목록과 크기(Size), 사용된 공간(Used), 빈 공간(Avail), 사용률(Use%), 해당 파일시스템이 연결되어 있는 디렉토리(Mounted on) 등이다. 기본 용량 단위는 du와 마찬가지로 1024바이트 기준이다. 

용량 표시를 좀더 읽기 편하게 보고 싶다면 -h 옵션을 이용하자. 메가 또는 기가바이트 단위로 표시해 준다. 

df -h

네트워크로 연결된 파일시스템(NFS)을 제외하고 현재 PC에 소속된 파일시스템(local file system) 만 보고 싶다면 -l 옵션을 사용. 

df -hl

 

 

Posted by 반달가면

댓글을 달아 주세요

리눅스 (backup)2021. 1. 6. 10:48

 

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

 

리눅스에서 특정 디렉토리가 얼마나 많은 용량을 차지하고 있는지 확인하고 싶으면 du 명령을 활용하자. 예를 들어 현재 디렉토리의 용량을 확인하려면 터미널창에서 아래와 같이 입력.

du ./

위와 같이 입력하면 현재 디렉토리와 그 하위 디렉토리를 나열하면서 각 디렉토리별로 어느 정도 용량을 점유하고 있는지 보여준다. 용량값은 1024바이트를 기준으로 한 것이다. (즉 용량값이 20이라고 나왔으면 1024*20=20480바이트)

만약 n바이트 단위로 용량을 표시하고 싶다면 -B 옵션을 사용하면 되겠다. 만약 512바이트를 1로 놓고 용량값을 표시하려면 아래와 같이 입력한다. (용량값은 1024바이트 기준보다 딱 2배 많게 표시될 것이다. 단위 크기가 반으로 줄었으므로)

du -B 512 ./

또 한가지 유용한 옵션은 맨 마지막에 해당 디렉토리의 총 용량을 표시해 주는 -c 옵션과 메가(M), 기가(G) 등의 단위를 표시해서 읽기 편하게 해 주는 -h 옵션이다. 예를 들어 홈 디렉토리 아래에 downloads 디렉토리의 용량을 확인하고 싶다면 아래와 같이 입력하면 되겠다.

du -ch ~/downloads
  -c : 마지막에 해당 디렉토리가 점유하는 총 용량을 표시
  -h : 사람이 읽기 좋게 표시(751876 -> 735M 이런 식으로)

하위 디렉토리의 용량을 일일이 확인할 필요 없이 해당 디렉토리의 총 용량만 보고 싶다면 grep을 활용하면 된다. 개인적으로 가장 자주 쓰는 형태다.

du -ch ~/downloads | grep total

 

 

 

Posted by 반달가면

댓글을 달아 주세요

bash script (backup)2020. 12. 28. 18:41

 

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

 

일단 통상적인 cut 명령부터. cut 명령을 사용하면 특정 구분자(-d 옵션)를 기준으로 앞에서부터 세서 특정 위치(-f 옵션)의 문자열을 가져올 수 있다. 아래의 예시를 보자.

# 구분자는 공백, 두번째 문자열 가져오기
echo "abc def:ghi jk l" | cut -d' ' -f2
def:ghi (출력 결과)

# 구분자는 콜론(:), 첫번째 문자열 가져오기
echo "abc def:ghi jk l" | cut -d':' -f1
abc def

자, 그렇다면 특정 구분자를 기준으로 뒤에서부터 순서를 세려면 어떻게 할 것인가? 즉, 위의 예시에서 뒤에서 두번째 문자열을 가져오는 문제이다.

이 문제를 해결하기 위해서는 rev 명령을 이용하면 된다. rev 명령은 문자열을 뒤에서 앞으로 재배열하는 기능을 해 준다. 아래의 예시를 보자.

# rev 명령을 이용해서 역순으로 재배열하기
echo "abcd" | rev
dcba (abcd의 역순 재배열)

이제 금방 감이 잡힐 것이다. 문자열을 뒤집은 후에 cut 명령으로 앞에서부터 순서를 센 후, 다시 뒤집으면 된다!

# 구분자는 공백, 뒤에서 두번째 문자열 가져오기
echo "abc def:ghi jk l" | rev | cut -d' ' -f2 | rev
jk

# 구분자는 콜론, 뒤에서 첫번째 문자열 가져오기
echo "abc def:ghi jk l" | rev | cut -d':' -f1 | rev
ghi jk l

 

# 파일의 확장자 식별하기 예시

file_name="J.S.Bach-Invention_No.1_BWV772.mp3"

file_ext=`echo "$filename" | rev | cut -d'.' -f1 | rev`

echo "the extension is $file_ext"

 

항목 수가 일정하지 않은 내용이 저장된 문서 파일에서 뒤쪽에서부터 단어를 세서 특정 위치의 단어를 뽑아내야 할 때 매우 요긴하게 사용할 수 있다.

 

 

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. 16. 17:41

 

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

 

shell script를 만들어 쓰다 보면 파일의 특정 행을 읽어서 이 행의 문자열들을 하나씩 가져다가 작업을 해야 하는 경우가 종종 생긴다.

 

 

예를 들어 people.txt에 이름과 이메일이 아래와 같은 형태로 저장되어 있다고 하자. 이름과 이메일 사이는 콜론(:)으로 구분한 경우이다.

 

john:john@mail.com

jane:jane@mail.com

 

이 파일에서 2번째 행, 즉 jane의 정보를 가지고 뭔가 작업을 하려고 한다면 script에 아래와 같은 내용이 들어갈 수 있다. (sed 명령에 대한 내용은 이전 게시물을 참고하자)

 

# people.txt에서 2번째 행을 뽑아서 data_str 변수에 저장

data_str=`sed -n 2p people.txt`

# 첫번째 필드를 name 변수에 저장

name=`echo $data_str | cut -d':' -f1`

# 두번째 필드를 email 변수에 저장

email=`echo $data_str | cut -d':' -f2`

# 이제 작업 시작

...

 

위의 예시는 별 문제가 없지만, 만약 구분자를 탭(tab)으로 사용한 파일을 다룰 때는 문제가 발생한다. 예를 들어 jane:jane@mail.com 대신 jane[탭]jane@mail.com 이런 형식으로 저장된 파일이라면 echo 명령으로 변수값을 출력할 때 잊지 말고 따옴표를 사용해 주자.

 

echo "$data_str" 이런 식으로 해야 한다. 따옴표를 사용하지 않으면 탭이 공백(space)으로 대체된다.

 

# data_str 변수에 jane[탭]jane@mail.com이 할당된 경우

echo $data_str

# 결과는 jane jane@mail.com (탭이 사라지고 공백으로 대체)

echo "$data_str"

# 결과는 jane[탭]jane@mail.com (탭이 보존됨)

 

따라서 탭을 구분자로 사용한 파일을 가지고 작업을 할 때는 앞의 예시가 아래와 같이 변경되어야겠다.

 

data_str=`sed -n 2p people.txt`

# data_str 변수로 받은 문자열의 구분자가 탭인 경우

# 첫번째 필드를 name 변수에, 두번째 필드를 email 변수에 저장

# cut 명령의 기본 구분자가 탭이므로 -d 옵션 불필요

name=`echo "$data_str" | cut -f1`

email=`echo "$data_str" | cut -f2`

 

성격이 꼼꼼하지 못해서 그런지 몇번이나 따옴표를 빼먹는 실수를... -_-;

 

 

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 반달가면

댓글을 달아 주세요