bash script (backup)2021. 3. 30. 17:24

 

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

 

파일은 그대로 놔두고 특정 디렉토리 하위에 있는 디렉토리 구조를 다른 디렉토리 하위에 복사하는 방법이다. find 명령을 사용해서 복사할 수 있다. (find 명령에 대한 소개는 이전 게시물을 참고하자. 여기로)

 

~/temp1/src 하위의 디렉토리 구조를 ~/temp2/dst 디렉토리로 복사하는 경우를 생각해 보자. 복사하고자 하는 원래 디렉토리로 간 후에 find 명령을 이용해서 디렉토리 구조를 출력하도록 한 후, -exec 옵션을 통해서 해당 출력물을 mkdir 명령의 인자(argument)로 대응시킨다.

cd ~/temp1/src
find ./ -type d -exec mkdir -p ~/temp2/dst/{} \;

find ./ -type d 명령에 의해 하위 디렉토리명을 찾은 후, 해당 결과에 대하여 -exec 옵션을 통해 mkdir 명령을 실행한다. mkdir 명령에서 {} 이 부분에 find의 결과가 인자로 들어가게 된다. -exec 옵션에 지정된 명령의 종료 지점을 표시하기 위해 세미콜론(;)을 사용하는데, 셸(shell)에서 명령어 구분자로 해석하는 것을 방지하기 위해 이스케이프(escape) 캐럭터인 역슬래시(\)로 보호해 준다.

참고로 mkdir 명령에 -p 옵션을 주면 필요할 경우 상위 디렉토리도 생성하라는 의미가 된다. 아래의 예시를 보자.

# ~/dir1 디렉토리가 없는 상태에서 실행할 경우 오류 발생
mkdir ~/dir1/dir2

# ~/dir1 디렉토리가 없다면 먼저 ~/dir1 디렉토리를 만든 후 dir2 디렉토리 생성(-p 옵션)
mkdir -p ~/dir1/dir2

 

Posted by 반달가면

댓글을 달아 주세요

bash script (backup)2021. 1. 28. 13:36

 

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

 

grep 명령을 이용하면 특정한 문자열을 포함하고 있는 파일들이 뭐가 있는지 찾을 수 있다. 훌륭하군!

일단 기본부터 차근차근 살펴보자. grep 명령의 기본 형식은 아래와 같다.

# [옵션]을 적용하여 [파일]의 내용을 검색, [문자열]을 찾음
grep [옵션] [문자열] [파일]

 

이제 아래의 예시를 보자. my_memo.txt 파일에서 abcd 문자열이 포함되어 있는지 검색하고 파일명과 함께 문자열이 포함된 행을 찾아 출력하는 것이다. -H 옵션을 주면 찾은 문자열뿐만 아니라 해당 파일명을 같이 출력해 준다. 파일명과 문자열은 콜론(:)으로 구분된다.

 

grep -H abcd my_memo.txt

my_memo.txt:abcdef

 

문자열은 필요 없고 파일명만 확인하고 싶다면 아래와 같이 -l 옵션을 추가하자.

 

grep -Hl abcd my_memo.txt

my_memo.txt

 

자, 이제 특정 디렉토리와 그 하위 디렉토리에 있는 여러개의 파일들 중에 특정한 문자열을 포함한 파일이 있는지 찾고 파일명을 확인해 보자. -r 옵션(recursive)을 이용하고 파일 대신 디렉토리를 지정하면 된다. 아래의 예시는 ~/Documents 디렉토리의 모든 파일을 검색, 내용에 abcd가 포함된 파일 찾아 파일명을 출력하는 경우이다.

 

grep -Hlr abcd ~/Documents

 

만약 특정 파일만 골라서 확인하고 싶다면 --include 옵션을 추가한다. 아래의 예시는 확장자가 txt인 파일만 대상으로 검색하는 경우이다.

 

grep -Hlr --include=*.txt abcd ~/Documents txt

 

파일 중에 v로 시작되는 파일은 제외하고 검색하려면 여기에 --exclude 옵션을 추가.

 

grep -Hlr --include=*.txt --exclude=v* abcd ~/Documents

 

 

Posted by 반달가면

댓글을 달아 주세요

bash script (backup)2020. 11. 10. 17:48

 

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

 

조금 단순하긴 하지만, 리눅스 셸 스크립트에서도 일반 프로그래밍 언어에서처럼 함수(function)를 만들어서 사용할 수 있다.

일단 형식은 아래와 같다.

function [함수 이름](){
...
return
}

함수를 호출할 때는 그냥 함수 이름을 쓰면 된다. 아래의 예시를 보자. 수자 2개를 인자로 받아서 앞의 수와 뒤의 수를 더한 후 이 값을 제곱하는 계산을 하는 함수를 만들어 보면 대략 아래와 같다. 함수 이름은 arith_test이고 스크립트 안에서 arith_test 3 4 이런 식으로 호출해서 쓰면 된다. bc 명령을 이용한 산수 계산은 이전 게시물을 참고하자.

# 함수 arith_test: f = (x+y)^2
function arith_test(){
  echo "( $1 + $2 )^2 | bc"
  return
}

# main
# 함수 호출. (4+5)^2 계산후 결과를 화면에 출력
arith_test 4 5
# 함수 호출. (3+4)^2 계산후 결과를 result 변수에 할당
result=`arith_test 3 4`

함수에서 계산한 결과를 변수에 할당할 경우, 가장 처음 echo 명령으로 출력된 결과가 변수에 할당된다. 위의 예시에는 echo 명령이 하나뿐이므로 상관 없다. 결과를 변수에 할당하는 방식을 쓰고 싶다면, 함수 안에 echo 명령은 하나만 있는 것이 좋겠다.

스크립트에서 사용하는 변수는 기본적으로 전역변수(global variable)이다. 만약 함수 안에서만 의미가 있는 지역변수(local variable)를 사용하고 싶다면 함수 안에서 변수이름 앞에 local을 붙이면 되겠다. 아래의 예를 보자.

function var_test(){
  local test_var_local="LOCAL"
  test_var_global="GLOBAL"
  return
}

# main
# 함수 호출
var_test
# 변수값 확인. test_var_local 값은 출력되지 않음(지역변수)
echo "$test_var_local"
echo "$test_var_global"

함수 기능은 때에 따라 아주 요긴하게 쓸 수 있다!


 

 

Posted by 반달가면

댓글을 달아 주세요

bash script (backup)2020. 10. 22. 12:17

 

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

 

텍스트 파일에서 2개 이상의 문자열을 검색하는 방법이다.

(A and B) 일단 A라는 문자열과 B라는 문자열이 모두 포함된 행을 찾는 것은 간단하다. 파이프(|)를 이용해서, A가 포함된 뿐을 골라낸 후에 거기서 B를 골라내면 된다.

 

cat file.txt | grep A | grep B

 

(A or B) A 또는 B가 포함된 행을 찾으려면 A와 B를 파이프(|) 기호로 연결하면 된다. 연산자로 인식하도록 역슬래시(\)를 붙여준다.

 

cat file.txt | grep "A\|B"

 

또는 egrep 명령을 활용해도 된다. 작은따옴표(')와 괄호를 이용한다.

 

cat file.txt | egrep '(A|B)'

 

만약 shell script에서 변수에 할당된 문자열을 사용하려고 한다면 egrep으로는 어렵고 앞에 언급한 파이프 기호를 이용해야 한다.

 

str_a="1st string"

str_b="2nd string"

cat file.txt | grep "$str_a\|$str_b"

 

Posted by 반달가면

댓글을 달아 주세요

bash script (backup)2020. 10. 19. 09:54

 

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

 

지난번에 적어 놓은 ssh 자동 접속 방법을 조금 확장시켜 볼 수 있겠다.

expect는 인자(argument)를 사용할 수 있기 때문에, 접속 주소나 암호 등을 script에 넣지 않고 인자로 지정할 수 있다. 실행 명령에 사용된 인자는 argv라는 이름의 변수로 가져온다.

 

예제 script 이름은 ssl_login2.exp로 하자. 인자 순서는 접속주소, 접속암호, 셸 프롬프트(shell prompt) 문자열 순서로 정하면 실행은 이런 식이 될 것이다.

 

expect -f ssl_login2.exp john@192.168.0.10 my_password "john>"

 

ssh서버 192.168.0.10에 john이라는 계정으로 접속하고 암호는 my_password인 경우이다. 로그인했을 경우 셸 프롬프트에 john>이라는 문자열이 들어있다고 가정했다. 셸 프롬프트를 인자로 가져오는 경우 bash에서 사용되는 특수 기호(>, | 등)가 포함되어 있다면 위의 예와 같이 반드시 따옴표 처리를 해 주자.

 

ssl_login2.exp script는 아래와 같이 만들면 되겠다. 인자로 받은 주소, 접속암호, 셸 프롬프트 문자열 값을 각각 addr, password, prompt 변수에 할당했다. 로그인 후에 하는 작업은 지난번처럼 그냥 커널 버전 확인만 하는 것으로 했다.

 

# script file: ssl_login2.exp

# version 2 (with argument support)

# set variables

set addr [lindex $argv 0]

set password [lindex $argv 1]

set prompt [lindex $argv 2]

# spawn ssh session

spawn ssh $addr

expect -nocase "password"

send "$password\r"

expect "$prompt"

# execute commands (in this example, 'uname -r')

send "uname -r\r"

expect "$prompt"

send "exit\r"

exit 0

 

각기 다른 서버에 들어가 같은 종류의 반복작업을 해야 할 경우 나름 편리하게 사용할 수 있다.

 

Posted by 반달가면

댓글을 달아 주세요

bash script (backup)2020. 10. 19. 09:48

 

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

 

앞에 게시한 ftp, telnet, ssh 자동접속 script를 사용할 경우 script에 접속 암호가 그대로 표시된다. 그러므로 반드시 해당 파일에 대한 접근권한을 제대로 설정해 주어야만 한다.

 

예를 들어 login.sh라는 파일을 만들었다면, 다른 사용자가 script 내용을 볼 수 없도록 권한을 설정해 주어야 한다.

ssh

chmod 700 login.sh

 

권한을 이렇게 해 놓아도 당연히 root는 해당 내용을 볼 수 있다. 자동접속 기능은 편리하긴 하지만 보안 측면에서는 분명히 위험요소가 있다는 점을 명심하고, 사용해도 괜찮은 상황인지 꼼꼼하게 따져 보고 결정하자.

 

Posted by 반달가면

댓글을 달아 주세요

bash script (backup)2020. 10. 19. 09:02

 

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

 

앞에서 올린 telnet 자동 접속 방법으로 ssh 접속은 불가능하다.

ssh 로그인을 자동화하려면 우선 expect를 설치해야 한다. 패키지 관리자에서 expect를 검색해서 설치하면 된다.

터미널창에서 설치하고 싶다면 아래와 같이 입력하면 되겠다.

sudo apt-get install expect
(데비안/우분투 계열 배포판)

또는

sudo zypper install expect
(오픈수세)

expect가 설치되었으면 이제 ssh 자동 접속을 해 보자.

 

예를 들어 ssh 서버가 192.168.0.10이고 사용자명은 john, 암호는 my_password라고 가정하자. 또한 서버에 로그인하면 셸 프롬프트(shell prompt)는 john> 이렇게 나온다고 가정하자. (셸 프롬프트가 어떤 형태로 표시되는지 미리 알고 있어야 한다)

 

처음 접속할 때는 암호화 통신을 위한 열쇠(RSA key)를 받아야 되니까 처음 한번은 수동으로 접속해서 열쇠를 받고, 그 다음부터 자동화 스크립트를 이용하면 되겠다. (만약 열쇠를 무조건 자동으로 받고 싶다면 ssh 접속에서 -o StrictHostKeyChecking=no 항목을 추가해야 한다. 아래 예시의 내용을 참고하자)

 

문서편집기를 이용해서 자동화 스크립트 ssl_login.exp를 아래와 같이 작성한다. #으로 시작되는 줄은 주석(comment)이다. 서버 192.168.0.10에 john이라는 사용자가 ssh 접속을 해서 서버의 커널 버전을 확인하기 위해 uname -r 명령을 실행한 경우이다.

 

# script file: ssl_login.exp

# spawn ssh process

spawn ssh john@192.168.0.10

# to accept RSA key automatically, set StrictHostKeyChecking=no

# spawn ssh -o StrictHostKeyChecking=no john@192.168.0.10

# wait for password request

expect -nocase "password"

# send password (\r is for return key)

send "my_password\r"

# wait for shell prompt expect "john>"

# execute commands (in this example, identify kernel version with 'uname -r' command)

send "uname -r\r"

# wait for user prompt

expect "john>"

# exit

send "exit\r"

 

위와 같이 스크립트를 만들었으면, 아래의 명령으로 실행하면 된다.

 

expect -f ssl_login.exp

 

여기에 사용된 expect 스크립트 명령어에 대해 간단히 적어 보자면,

 

spawn: 새로운 프로세스를 실행한다

 

expect: 특정 문자열이 나올 때까지 기다린다. -nocase 옵션을 주면 대소문자를 구별하지 않는다.

 

send: 특정 문자열을 실행중인 프로세스로 보낸다. 명령어를 입력하고 엔터를 누르는 경우 마지막에 \r 추가.

 

Posted by 반달가면

댓글을 달아 주세요

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

 

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

 

telnet 로그인을 자동화하는 방법이다.

 

telnet 서버가 192.168.0.10이고 사용자명은 john, 암호는 my_password라고 가정하면, 아래와 같은 shell script를 이용할 수 있다. telnet으로 접속해서 uname -r 명령으로 서버의 커널 버전을 확인하는 경우다.

 

(

sleep 2

echo "john"

sleep 2

echo "my_password"

sleep 2

echo "uname -r"

sleep 2

echo "exit" ) | telnet 192.168.0.10

 

입력을 보낸 후 응답이 올 때까지 걸리는 시간을 고려해서 각 입력 사이에 몇초간 대기하도록 sleep 명령을 사이사이에 추가해 주는 것이 좋다.(위의 예시에서는 2초)

 

 

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

댓글을 달아 주세요

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

 

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

 

리눅스 shell script에서 FTP 서버에 자동으로 접속해서 파일을 올리거나 가져오는 방법이다.

 

형식은 대략 아래와 같다.

 

ftp -n [서버 주소] << [구분자]

user [사용자id] [암호]

[ftp 명령어]

quit

[구분자]

 

예를 들어 사용자 이름 john, 암호 my_password, ftp 서버 192.168.0.10, my_data.dat 파일을 가져오는 경우라면 이렇게 만들면 되겠다.

 

ftp -n 192.168.0.10 << SCRIPT

  user john my_password

  binary

  get my_data.dat

  quit

SCRIPT

 

구분자로 사용한 SCRIPT는 들여쓰기(indentation)하면 안된다는 점에 주의하자. 구분자 위쪽의 ftp 명령어 부분은 들여쓰기해도 된다.

 

ftp에서 -n 옵션은 접속후 자동으로 계정과 암호를 묻지 않도록 하기 위한 것이다. 계정과 암호는 "SCRIPT"라는 구분자로 묶인 부분에서 수동으로 입력하므로 자동접속에서는 -n 옵션이 반드시 포함되어 있어야 한다.

 

만약 script 구성상 전체적으로 들여쓰기를 해야 보기가 좋다면 아래와 같이 해 보자. ("<<" 대신 "<<-" 사용)

 

  ftp -n 192.168.0.10 <<- SCRIPT

    user john my_password

    binary

    get my_data.dat

    quit

  SCRIPT

 

한가지 유의할 점은, 들여쓰기를 할 때 반드시 탭(tab)을 사용해야 한다는 것이다. 공백(space)으로 들여쓰기를 하면 안 된다.

 

FTP는 접속정보가 암호화되지 않으므로 보안에 유의하자! 되도록 anonymous 사용을 추천.

 

 

Posted by 반달가면

댓글을 달아 주세요