Day62

2021. 1. 11. 12:22교육과정/KOSMO

키워드 : 파이썬 함수 개념 추가 / 파이썬 지역 변수 / 파이썬 글로벌 변수 / 파이썬 맵리듀스 / 리눅스 조건 연산자 / 리눅스 파일 관련 옵션 / 리눅스 논리 연산자 / 리눅스 반복문 for, while / 리눅스 쉘 함수 호출 / 아파치 플럼 다운로드 및 설치

 

 

****

 

 

0. 파이썬 복습

   (1) unpacking

  list = [1, 2, 3] 
  a, b, c = list 


   (2) compregension
        : 요소 생성시 for 문과 if문 결합

  list = [i for i in range(10, 100, 10) if i <=50 ] 
  list = [10, 20, 30, 40, 50] 


   (3) 함수의 인자

  *args : 여러 개의 인자를 하나의 튜플로 받아서 처리 
  **kwargs : 여러 개의 인자를 하나의 딕셔너리로 받아서 처리

 

※ 복습 연습문제 

 

(1) 다음과 같이 코드를 작성했을 때, 실행 결과로 알맞은 것은?

  mylist = ['apple' ,'banana', 'grape']
  result = list(enumerate(mylist))
  print(result)

➀ [('apple', 1), ('banana', 2), ('grape', 3)]

➁ [(1, 'apple'), (2, 'banana'), (3, 'grape')]

➂ [(0, 'apple'), (1, 'banana'), (2, 'grape')]

➃ [('apple', 0), ('banana', 1), ('grape', 2)]

➄ [('grape',0), ('banana',1), ('apple',2)]

답 : ③

(풀이)

enumerate()는 순서를 붙여 튜플로 만드는 함수 
[(0, apple), (1, banana), (2, grape)]

 

(2) 다음과 같이 코드를 작성했을 때, 실행 결과로 알맞은 것은?

  cat_song = "my cat has blue eyes, my cat is cute"
  print({i:j for j,i in enumerate(cat_song.split())})

➀ {0: 'my', 1: 'cat', 2: 'has', 3: 'blue', 4: 'eyes,', 5: 'my', 6: 'cat', 7: 'is', 8: 'cute'}

➁ {'my': 0, 'cat': 1, 'has': 2, 'blue': 3, 'eyes,': 4, 'my': 5, 'cat': 6, 'is': 7, 'cute': 8}

➂ {0: 'my', 1: 'cat', 2: 'has', 3: 'blue', 4: 'eyes,', 5: 'is', 6: 'cute'}

➃ {'my': 5, 'cat': 6, 'has': 2, 'blue': 3, 'eyes,': 4, 'is': 7, 'cute': 8}

➄ 오류

답 : ③

(풀이)

enumerate(cat_song.slit()) == (0, my) (1, cat) (2, has) (3, blue) (4, eyes,) (5, my) (6,cat) (7, is) (8, cute)
{i:j} == { my:0, cat:1, has:2, blue:3, eyes,:4, 
           my:5, cat:1, has:2, blue:3, eyes,:4, 
           my:5, cat:6, has:2, blue:3, eyes,:4, is:7, cute:8 }

딕셔너리에서 중복이 제거되면서 같은 key값의 value는 나중 것으로 덮어씌여진다. 

 

(3) 다음과 같이 코드를 작성했을 때, 예측되는 실행 결과를 쓰시오.

  colors = ['orange', 'pink', 'brown', 'black', 'white']
  result = '&'.join(colors)
  print(result)

답 : 

orange&pink&brown&black&white

(풀이)

join( ) 함수는 특정 문자열로 리스트를 구분지어준다.

 

(4) 다음 코드의 실행 결과를 쓰시오.

  user_dict = {}
  user_list = ["students","superuser", "professor", "employee"]
  for value_1, value_2 in enumerate(user_list):
      user_dict[value_2] = value_1
  print(user_dict)

답 : 

{'students': 0, 'superuser': 1, 'professor': 2, 'employee': 3}

(풀이)

user_list = ["students","superuser", "professor", "employee"] 일 때,
enumerate(user_list) == (0, students), (1, superuser), (2, professor), (3, employee)

user_dict[value_2] = value_1 에서 value_2가 key가 되고 value_1이 value가 되므로,
{'students': 0, 'superuser': 1, 'professor': 2, 'employee': 3}

 

(5) 다음 코드의 실행 결과를 쓰시오.

  animal = ['Fox', 'Dog', 'Cat', 'Monkey', 'Horse', 'Panda', 'Owl']
  print([ani for ani in animal if 'o' not in ani])

답 : 

['Cat', 'Panda', 'Owl']

(풀이)

[ani for ani in animal if 'o' not in ani] 를 풀어 쓰면

    if 'o' not in ani:
        ani for ani in animal: 이므로,
    ani는 'o'를 포함하지 않는 요소로 이루어진 리스트가 된다. 

 

(6) 다음 코드의 실행 결과를 쓰시오.

  name = "Hanbit University"
  student = ["Hong", "Gil", "Dong"]
  split_name = name.split()
  join_student = ''.join(student)
  print(join_student[-4:] + split_name[1])

답 : 

DongUniversity

(풀이)

split_name = ["Hanbit", "University"]
join_student = 'HongGilDong'
join_student[-4:] == 'Dong'
split_name[1] == 'University'
print(join_student[-4:] + split_name[1]) == DongUniversity

 

(7) 다음과 같은 결과값을 출력하기에 적당한 함수를 빈칸에 쓰시오.

  >>> alist = ['a1', 'a2', 'a3']
  >>> blist = ['b1', 'b2' ,'b3']
  >>> for a, b in             (alist, blist):
  print(a, b)

  a1 b1
  a2 b2
  a3 b3

답 : 

zip

 

 

(8) 다음과 같이 코드를 작성했을 때, 예측되는 실행 결과를 쓰시오.

   >>> a = [1, 2, 3]
   >>> b = [4, 5, ]
   >>> c = [7, 8, 9]
   >>> print([[sum(k), len(k)] for k in zip(a, b, c)])

① [[6, 3], [9, 2], [24, 3]]

② [[12, 3], [15, 3]]

③ [[12, 3], [15, 3], [17, 3]]

④ 오류

⑤ [[12, 3], [15, 3], [12, 2]]

답 : ②

(풀이)

zip(a, b, c)의 결과는 [ (1, 4, 7), (2, 5, 8) ] 이고,
for k in zip(a, b, c)의 결과는 (1, 4, 7)과 (2, 5, 8) 이다. 
sum(k)의 결과는 1+4+7=12 와 2+5+8=15 이고,
len(k)의 결과는 3과 3 이므로
print([[sum(k), len(k)] for k in zip(a, b, c)]) 의 실행결과는 
[ [12, 3], [15, 3] ] 가 된다. 

 

(9) 다음 코드의 실행 결과를 쓰시오.

  week = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']
  rainbow = ['red', 'orange', 'yellow', 'green', 'blue', 'navy', 'purple']
  list_data = [week, rainbow]
  print(list_data[1][2])

답 : 

yellow

(풀이)

list_data[1] 는 rainbow 이고
list_data[1][2] 는 rainbow[2] 를 가리키므로 yellow가 출력된다. 

 

(10) 다음 코드의 실행 결과를 쓰시오.

  kor_score = [30, 79, 20, 100, 80]
  math_score = [43, 59, 0, 30, 90]
  eng_score = [49, 72, 48, 67, 15]
  midterm_score = [kor_score, math_score, eng_score]
  print ("score:",midterm_score[2][1])

답 : 

score:72

(풀이)

midterm_score[2] 는 eng_score 이고
midterm_score[2][1] 는 eng_score[1] 에 해당한다.
따라서, print(midterm_score[2][1]) 를 실행하면 72 가 출력된다.

 

(11) 다음 코드의 실행 결과를 쓰시오.

  alist = ["a", "b", "c"]
  blist = ["1", "2", "3"]
  abcd= []
  for a, b in enumerate(zip(alist, blist)):
      try:
          abcd.append(b[a])
      except IndexError:
          abcd.append("error")
  print(abcd)

답 :

['a', '2', 'error']

(풀이)

zip(alist, blist) 는 ('a', '1') ('b', '2') ('c', '3') 이고,
enumerate() 를 적용하면 
(a, b)의 튜플 구조를 갖는 (0, ('a', '1')) (1, ('b', '2')) (2, ('c', '3')) 가 된다. 
a : 0, 1, 2
b : ('a', '1'), ('b', '2'), ('c', '3')
따라서, b[a] 는 ('a', '1')[0] == 'a'
                ('b', '2')[1] == '2'
                ('c', '3')[2] == 없음 .. 'error'
실행결과 abcd = ['a', '2', 'error'] 가 출력된다. 

 

(12) 다음 코드의 실행 결과를 쓰시오.

  alphabet = ["a", "b", "c", "d", "e", "f", "g", "h"]
  nums = [i for i in range(20)]
  answer = [alpha+str(num) for alpha in alphabet for num in nums if num%2==0]
  print(len(answer))

답 : 80

alphabet = ["a", "b", "c", "d", "e", "f", "g", "h"] 총 8개
nums == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] 총 20개
alpha for alpha in alphabet == ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']

for alpha in alphabet for num in nums if num%2==0 를 풀어 쓰면

if num % 2 == 0
    for num in nums:
        for alpha in alphabet: 이므로
num 이 짝수일 때 반복문에서 num * alpha 횟수만큼 두 종류의 문자가 결합한다. 

len(answer) 은 answer 에 있는 요소의 갯수를 구하는 것이므로 8 * 10 = 80 이 출력된다. 

print(answer) = ['a0', 'a2', 'a4', 'a6', 'a8', 'a10', 'a12', 'a14', 'a16' ...  'h14', 'h16', 'h18']

 


1. 파이썬 함수 개념 추가

 

(1) 함수도 메모리에 올라가는 객체가 될 수 있다. 

def case1():
    print('case-1')

def case2():
    print('case-2')

def case3():
    print('case-3')

f = {'case1':case1, 'case2':case2, 'case3':case3}
a = 'case3'

f[a]        # f['case3'] == case-3
f[a]()

# 실행결과
'''
case-3
'''

 

(2) 자바에서의 지역변수와 파이썬에서의 지역변수

   # JAVA : 블록 안에서 선언한 변수가 지역 변수
   # 파이썬 : 함수 안에서 선언한 변수가 지역 변수
if True:
    test = '변수'
print(test)

# 실행결과
'''
변수... if 문은 함수가 아니다! 제어문이다.
'''

 

(3) 파이썬에서의 글로벌 변수와 지역 변수

   # 함수 안에서 선언한 변수는 지역변수가 된다. 
temp = '글로벌'

def func():
#   print('0>', temp) ... 지역변수가 있을 경우에는 지역변수 선언보다 앞에서 변수를 사용할 수 없다.
    temp = '지역'
    print('1>', temp)
func()                 
print('2>', temp)       

# 실행결과
'''
1>지역
2>글로벌
'''

 

   # 지역변수는 함수 밖에서 글로벌변수로 사용할 수 없다. 
def func():
    temp = '지역'
    print('1>', temp)
func()                  
# print('2>', temp) ... 에러 발생

# 실행결과
'''
1> 지역
'''

 

   # 함수 안에서 global 이라고 선언해줄 경우, 지역변수가 아닌 글로벌 변수가 되어 함수 밖에서도 사용할 수 있다. 
def func():
    global temp
    temp = '지역'
    print('1>', temp)
func()
print('2>', temp)

# 실행결과
'''
1> 지역
2> 지역
'''

 

(4) 람다 함수

  # 람다함수 - 한번 사용하고 버리는 함수
  # 파이썬에서는 람다함수를 한 줄로 작성하기도 한다. 
  # 람다함수 사용시 직관적이지 않다는 이유로 파이썬 3.x부터는 람다를 권장하지 않는 경우가 많으나 종종 사용된다.
# original 함수 --- 2줄
def f(x,y):
    return x*y
print(f(2,3))

# 실행결과
'''
6
'''

 

# lambda 함수 (축약형) --- 1줄
f = lambda x,y: x*y
print(f(2,3))

# 실행결과
'''
6
'''

 

(5) 맵리듀스 

    (1) map()
         ` 연속 데이터를 저장하는 시퀀스 자료형에서 요소마다 같은 기능을 적용할 때 사용
         ` 형식 : map(함수명, 리스트형식의 입력값)
         ` 파이썬 3.x에서는 list(map(calc, ex)) 반드시 list를 붙여야 리스트 형식으로 반환된다
           파이썬 2.x에서는 list 없이도 리스트 형식으로 반환
    (2) reduce()
         ` 리스트 같은 시퀀스 자료형에 차례대로 함수를 적용하여 모든 값을 통합하는 함수    
    
    파이썬 2.x에서는 많이 사용하던 함수이지만, 최근 문법의 복잡성으로 권장하지 않는 추세이다.

 

(1) 맵 map( )

※ map(a, b) 사용시 b 에서 요소를 하나씩 뽑아서 a 에 넣어서 연산을 수행하고,
    결과를 출력하기 위해서는 리스트( list )를 사용한다.

※ 함수의 인자로 리스트의 요소를 하나씩 넣고 결과 역시 리스트로 받을 수 있다. 

def calc(x):
    return x**2
ex = [1,2,3,4,5]
map (calc, ex)
print(list(map(calc, ex)))

# 실행결과
'''
[1, 4, 9, 16, 25]
'''

 

(2) 리듀스 reduce( )

    ※ reduce 클래스를 import 해야 한다. 

    ※ reduce(a, b) 사용시 b 에서 요소를 하나씩 뽑아서 a 에 넣어서 연산을 수행하고,

       그 결과값들로 다시금 연산하여 최종 하나의 값을 얻는다. 

    → 차례대로 뽑는다. → 함수를 수행한다. → 모든 값을 통합한다. 

from functools import reduce
def f(x,y):
    return x*y
print(reduce(f, range(1,6)))

# 실행결과
'''
120
'''

(풀이)

range(1,6) == [1,2,3,4,5]
def f(x, y) = x * y
reduce(f, range(1,6)) == [1,2,3,4,5]
                   1 * 2 = 2  ┘
                     2 * 3 = 6  ┘
                       6 * 3 = 24 ┘
                         24 * 5 = 120

 


※ 연습문제

 

(1) 다음 코드를 람다 함수 형태로 수정할 때, 알맞은 코드를 작성하시오.

   def f(x, y):
   return x ** y

답 : 

f = lambda x,y: x**y

(풀이)

람다 함수로 작성시에는, 인자를 먼저 적고 : 이후에 리턴값을 작성한다. 

 

(2) 다음과 같이 리스트 컴프리헨션으로 되어 있는 코드를 람다(lambda) 함수와 map() 함수를 사용하여 표현하시오.

  >>> ex = [1, 2, 3, 4, 5]
  >>> [value **2 for value in ex]
  [1, 4, 9, 16, 25]

답 : 

f = lambda x : x**2
print(list(map(f, ex)))

print(list(map(lambda x : x**2, [1,2,3,4,5]) ) )

# 실행결과
'''
[1, 4, 9, 16, 25]
'''

(풀이)

[value **2 for value in ex] 는 
리스트 ex 의 요소를 하나씩 뽑아낸 뒤, 제곱을 한 결과가 들어있는 리스트이다. 

함수를 람다식으로 나타내면 f = lambda x : x**2 이고,
map(f, ex) 의 결과를 리스트로 출력하려면 print(list(map(f, ex)))가 된다. 

 

(3) 다음과 같이 코드를 작성했을 때, 예측되는 실행 결과를 쓰시오.

   >>> def transpose_list(two_dimensional_list):
   ... return [row for row in zip(*two_dimensional_list)]
   ...
   >>> transpose_list([[1, 4, 7], [2, 5, 8], [3, 6, 9]])

답 :

[ (1,2,3) (4,5,6) (7,8,9) ]

(풀이)

실행될 함수는 
def transpose_list(two_dimensional_list):return [row for row in zip(*two_dimensional_list)] 이다.

return [row for row in zip(*two_dimensional_list)] 는
two_dimensional_list 전체를 받아서 zip( ) 함수로 새로운 튜플 구조를 만든다. 
[[1, 4, 7], [2, 5, 8], [3, 6, 9]] 에 zip( ) 함수가 적용된 튜플 구조는 
(1,2,3) (4,5,6) (7,8,9) 이고, 
리스트로 전체를 감싸면 [ (1,2,3) (4,5,6) (7,8,9) ] 가 출력된다.

 

(4) 다음 코드의 실행 결과를 쓰시오.

  >>> date_info = {'year': "2019", 'month': "9", 'day': "6"}
  >>> result = "{year}-{month}-{day}".format(**date_info)
  >>> result

답 : 

2019-9-6

(풀이)

date_info는 딕셔너리 구조이며 key와 value에 따른 출력은 
{'year': "2019", 'month': "9", 'day': "6"} 이다. 

key값인 year, month, day 에 해당하는 value를 출력하면 
2019-9-6 이 출력된다. 

 

(5) n개의 벡터의 크기가 동일한지 확인하는 함수를 한 줄의 코드로 작성하시오.

  a=(1,2,3)
  b=(4,5,6)
  c=(6,7,9)
  print(vector_size_check(a,b,c)) # True

 

  a=(1,2,3)
  b=(4,5,6)
  c=(6,7)
  print(vector_size_check(a,b,c)) # False

 

답 : 

vector_size_check = lambda a,b,c: len(a)==len(b)==len(c) 

(풀이)

len(a)==len(b)==len(c) 의 결과는 True 또는 False로 나오게 된다. 

 

(6) 다음과 같이 2개 이상의 행렬을 더하는 코드를 작성하시오. [ 답제공 ]

   >>>matrix_y = [[2, 5], [2, 1]]
   >>>matrix_z = [[2, 4], [5, 3]]
   >>>matrix_addition(matrix_y, matrix_z)
   [[4, 9], [7, 4]]

답 : 

(풀이)

matrix_addition = lambda a,b : a[0]*b[0]


   >>>matrix_y = [[2, 5], [2, 1]]
   >>>matrix_z = [[2, 4], [5, 3]]
   >>>matrix_addition(matrix_y, matrix_z)
   [[4, 9], [7, 4]]

2. 리눅스 - 조건 연산자

 

※ 리눅스에서 한 줄씩 입력하는 대신 여러 줄을 한 번에 입력하기  위해 쉘 프로그래밍을 활용할 수 있다. 

※ 컴파일 언어가 아니기 때문에 문법 오류를 찾아내기 어렵다. 

   * 조건연산자
   -eq    값이 같다 (equal)
   -ne    값이 다르다 (not equal)
   -gt    값1이 값2보다 크다 (greater than)
   -ge    값1이 값2보다 크거나 같다 (greater or equal)
   -lt    값1이 값2보다 작다 (less than)
   -le    값1이 값2보다 작거나 같다 (less or equal)
   -!    조건이 성립하지 않음

 

(1) root 계정 로그인 후 shelltest 디렉토리로 이동한다. 

[root@localhost shelltest]# cd shelltest
[root@localhost shelltest]# pwd
/root/shelltest

 

(2) vi 에디터로 condi3.sh 파일을 생성하고 작성 후 저장한다. 

[root@localhost shelltest]# vi condi3.sh
i
#!/bin/sh

if [ 100 -eq 200 ]
then
	echo "같다"
else
	echo "다르다"
fi

exit 0
:wq

 

(3) sh 명령어로 condi3.sh 파일을 실행하여 결과를 확인한다. 

[root@localhost shelltest]# sh condi3.sh

 


 

3. 리눅스 - 파일 관련 옵션

 

  * 파일 관련 옵션
 -f  : 파일이면 True
 -d  : 디렉토리이면 True
 -e   : 존재하면 True
  -r    : 읽기 가능하면 True
 -w   : 쓰기 가능하면 True
 -x   : 실행 가능하면 True
 -s  
 : 파일의 크기가 0이 아니라면 true

 

(1) 파일 관련 옵션을 테스트 하기 위한 condi4.sh 파일을 vi 에디터로 생성한다.

    테스트 할 옵션 : -f .......... fn이 파일인가?
[root@localhost shelltest]# vi condi4.sh
i
#!/bin/sh

fn=/root/anaconda-ks.cfg

if [ -f $fn ]
then
	head -5 $fn
else
	echo 'not a file'
fi

exit 0
:wq

 

(2) 파일이면 5줄을 출력하고, 아닐 경우 echo의 내용을 출력하는지 확인하기 위해 sh 명령어로 condi4.sh를 실행한다.

    실행결과 : 파일 O, 조건문에 의해 상위 5라인이 출력된다. 
[root@localhost shelltest]# sh condi4.sh
#version=DEVEL
# System authorization information
auth --enableshadow --passalgo=sha512
# Use CDROM installation media
cdrom

 

(3) 실행시 파일명을 함께 입력하면 조건문에서 결과에 따라 출력되도록 쉘 스크립트를 수정한다. 

    테스트 할 옵션 : -f ..........명령행 매개변수( $1 )로 읽어오는 이름 fn이 파일인가?
#!/bin/sh

fn=$1

if [ -f $fn ]
then
	head -5 $fn
else
	echo 'not a file'
fi

exit 0

 

(4) 매개변수에 따른 출력결과가 알맞은지 확인한다. 

    실행결과 ① : 파일 O, 조건문에 의해 상위 5라인이 출력된다. 
    실행결과 ② : 파일 X, 조건문에 의해 not a file 이라고 출력된다. 

# ①
[root@localhost shelltest]# sh condi4.sh /root/anaconda-ks.cfg
#version=DEVEL
# System authorization information
auth --enableshadow --passalgo=sha512
# Use CDROM installation media
cdrom

# ②
[root@localhost shelltest]# sh condi4.sh /root
not a file

 


4. 리눅스 - 논리 연산자

 

  * 논리연산자  : && ,   | |
   if [ A ] && [ B ]        if [ A ] -a [ B ]
   if [ A ]  | |  [ B ]        if [ A ] -o [ B ]

   ※ 주의   if [ A && B ] 는 안 된다.

 

(1) 논리연산자 옵션을 테스트 하기 위해 condi4.sh 파일을 vi 에디터로 수정한다.

     두 가지 조건을 모두 충족하는지 확인하기 위해 && 연산자를 사용한다. 

     테스트 할 옵션 : -f ..........명령행 매개변수( $1 )로 읽어오는 이름 fn이 파일인가?
     테스트 할 옵션 : -s ..........명령행 매개변수( $1 )로 읽어오는 이름 fn의 용량은 0보다 큰가?

#!/bin/sh

fn=$1

if [ -f $fn ] && [ -s $fn ]
then
        head -5 $fn
else
        echo 'not a file'
fi

exit

 

(2) 매개변수가 포함된 sh 명령어를 입력하여 논리연산자의 수행 결과를 확인한다. 

    실행결과 ① : 파일 O && 용량이 0보다 큼, 조건문에 의해 상위 5라인이 출력된다. 
[root@localhost shelltest]# sh condi4.sh ./var1.sh
#!/bin/sh

myvar='Hello'

echo $myvar

 

(3) 두 가지 조건을 모두 충족하는지 확인하기 위해 -a 연산자를 사용한다. 

     테스트 할 옵션 : -f ..........명령행 매개변수( $1 )로 읽어오는 이름 fn이 파일인가?
     테스트 할 옵션 : -s ..........명령행 매개변수( $1 )로 읽어오는 이름 fn의 용량은 0보다 큰가?
#!/bin/sh

fn=$1

if [ -f $fn -a -s $fn ]
then
	head -5 $fn
else
	echo 'not a file'
fi

exit

 

(4) 매개변수가 포함된 sh 명령어를 입력하여 논리연산자의 수행 결과를 확인한다. 

    실행결과 ① : 파일 O && 용량이 0보다 큼, 조건문에 의해 상위 5라인이 출력된다. 
[root@localhost shelltest]# sh condi4.sh ./var1.sh
#!/bin/sh

myvar='Hello'

echo $myvar

 


5. 리눅스 - 반복문

 

(1) for

①  for  변수  in  값1 값2 값3
     do
             반복실행문장
     done
②  for  변수  in `seq 초기값  마지막값`           ※ 역따옴표 주의!
     do
             반복실행문장
     done
③  for ( ( 초기값 ; 조건문 ; 증가치 ) )
     do
            반복실행문장
     done  
for  i  in  { 초기값 .. 마지막값 }
    do
            반복실행문장
    done    

(2) while

 ① while [ 조건문 ]
     do
            반복실행문장
     done

(3) break / continue
(4) 함수 / return

 


6. 리눅스 - 반복문 연습문제 (1)

 

(1) for 반복문 실습을 위해 condi5.sh 파일을 vi 에디터로 생성한다. 

[root@localhost shelltest]# vi condi5.sh
i

 

(2) 1~5까지의 합을 구하는 쉘 스크립트를 작성한다. 

#!/bin/sh

result=0

for i in 1 2 3 4 5
do
        result=`expr $result + $i`      # 역따옴표 주의!
done

echo 'sum=' $result
:wq

 

(3) sh 명령어로 실행하여 반복문 안의 연산 결과가 정상적으로 수행되는지 확인한다. 

[root@localhost shelltest]# sh condi5.sh

 

(4) 다른 종류의 for문을 사용하여 같은 결과를 출력해본다. 

#!/bin/sh

result=0

① for i in `seq 1 5`
② for ((i=1;i<6;i++))
③ for i in {1..5}
do
	result=`expr $result + $i`	# 역따옴표 주의!
done

echo 'sum=' $result

 


※ [ 예제 ] 1부터 100까지 수에서 홀수의 합과 짝수의 합 출력

   ★ ( `expr` 밖에서 =과 +연산자에 공백을 주지 않도록 한다. )

#!/bin/sh

for i in `seq 1 100`
do
	if [ `expr $i %  2` == 0 ]
	then
		even=`expr $even + $i`
	else
		odd=`expr $odd + $i`
	fi
done

echo "짝수의 합 : "$even
echo "홀수의 합 : "$odd

exit 0

( 실행결과 )

짝수의 합 : 2550
홀수의 합 : 2500

7. 리눅스 - 반복문 연습문제 (2)

 

(1) 파일명을 for 반복문에서 사용하기 위해 condi7.sh 파일을 vi 에디터로 생성한다. 

[root@localhost shelltest]# vi condi7.sh

 

(2) 쉘 스크립트를 작성한다.

   condi로 시작하는 . sh 파일 목록에서 파일 이름에 해당하는 fname을 출력하는 반복문을 작성한다. 
#!/bin/sh

for fname in $(ls condi*.sh)
do
	echo $fname
done

 

(3) 출력결과를 확인한다. 

[root@localhost shelltest]# sh condi7.sh
condi.sh
condi2.sh
condi3.sh
condi4.sh
condi5.sh
condi7.sh

 


8. 리눅스 - 반복문 연습문제 (3)

 

(1) 파일명을 매개변수로 받아 반복문에서 사용하기 위해 condi7.sh 파일을 vi 에디터로 연다. 

[root@localhost shelltest]# vi condi7.sh
i

 

(2) 쉘 스크립트를 수정한다. 

   condi로 시작하는 . sh 파일 목록에서 각 파일마다
   filename 이라는 key 값에 대해

   이름에 해당하는 fname을 출력하는 반복문을 작성한다. 
#!/bin/sh

for fname in $(ls condi*.sh)
do
	echo 'filename:' $fnamedone
	tail -3 $fname
done
:wq

 

(2) 결과를 출력해본다. 

filename:
fi


filename:
	stop )  echo "종료합니다" ;;
	* )  echo "start 또는 stop을 입력해주세요" ;;
esac
filename:
fi

exit 0
filename:
fi

exit
filename:

echo 'sum=' $result

filename:
	echo 'filename:' $fnamedone
	tail -3 $fname
done

 


※ while 문 실습

[ 연습 ] 1부터 10까지의 합 출력

 

[ 실행 ] sh condi8.sh

[ 프로세스 확인 ] ps -ef | grep condi8.sh

                       컴퓨터 학대 중이라면

[ 프로세스 종료 ] kill -9 PID값

 

[root@localhost shelltest]# vi condi8.sh
i
#!/bin/sh

sum=0
i=0
while [ $i -le 10 ]
do
	sum=`expr $sum + $i`
	i=`expr $i + 1`
done

echo "1부터 10까지의 합:" $sum
exit 0
:wq

 


9. 리눅스 쉘 함수 호출

    : 사용자로부터 입력된 값 num1과 num2가 add 라는 함수를 호출할 때 인자로 들어가서 나머지 연산이 수행된다. 

      (명령행 매개변수가 처리되는 방식과 비슷한듯!!)

#!/bin/sh

#함수 선언
add()
{
	total=`expr $1 + $2`
	echo 'total=' $total
}

#함수 호출
echo 'enter first number:'
read num1
echo 'enter second number:'
read num2

add $num1 $num2

(실행결과)

[root@localhost shelltest]# ./condi9.sh
enter first number:
1
enter second number:
2
total= 3

 


10. 아파치 플럼 설치

 

※ 아파치 플럼 ( Apache Flume ) ?

   : 연속적으로 생성되는 데이터 스트림을 HDFS 에 수집 및 전송하고 저장하는데 사용되며, 

     통신 프로토콜, 메시지 포맷, 발생주기, 데이터 크기 등과 관련된 여러가지 기능과 아키텍처를 제공한다. 

   : 데이터 스트림에는 로그파일, 소셜 미디어 데이터, 이메일 메시지 등이 있다. 

[ 플럼 참고 ] kerpect.tistory.com/62

[ 카프카 참고 ] kerpect.tistory.com/63?category=874039

 

 

※ 아파치 홈페이지에서 파일만 다운 받을 수 있는 경로

 

(1) 리눅스의 파이어폭스에서 http://apache.mirror.cdnetworks.com/ 접속

 

(2) 목록에서 flum/  클릭

 

(3) 목록에서 1.9.0/ 클릭 

 

(4) 웹페이지 주소와 apache-flume-1.9.0-bin.tar.gz 라는 파일명을 합친다. 

http://apache.mirror.cdnetworks.com/flume/1.9.0/apache-flume-1.9.0-bin-tar.gz 

(주소창에 위의 내용을 입력했을 때 다운로드가 바로 나타나야 정상적이다. )

 

(5) 리눅스 터미널에서 /home/centos 디렉토리로 이동 후 tmp 디렉토리를 생성한다. 

[root@localhost centos]# mkdir tmp
[root@localhost centos]# ls
abc    test    tmp    공개    다운로드    문서    바탕화면    비디오    사진    서식    음악
 

 

(6) 작업경로를 tmp 디렉토리로 변경한다. 

[root@localhost centos]# cd tmp

 

(7) 터미널에서 wget 명령어를 사용하여 설치파일을 다운받는다. 

[root@localhost tmp]# wget apache.mirror.cdnetworks.com/flume/1.9.0/apache-flume-1.9.0-bin.tar.gz
--2021-01-14 18:39:19--  http://apache.mirror.cdnetworks.com/flume/1.9.0/apache-flume-1.9.0-bin.tar.gz
Resolving apache.mirror.cdnetworks.com (apache.mirror.cdnetworks.com)... 14.0.101.165
Connecting to apache.mirror.cdnetworks.com (apache.mirror.cdnetworks.com)|14.0.101.165|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 67938106 (65M) [application/x-gzip]
Saving to: ‘apache-flume-1.9.0-bin.tar.gz’

100%[===================================>] 67,938,106  40.1MB/s   in 1.6s   

2021-01-14 18:39:21 (40.1 MB/s) - ‘apache-flume-1.9.0-bin.tar.gz’ saved [67938106/67938106]

 

(8) tmp 디렉토리에 아파치 플럼 설치파일이 다운받아져 있는지 확인한다. 

[root@localhost tmp]# ls
apache-flume-1.9.0-bin.tar.gz 

 

(9) gzip 파일의 압축을 풀기 위해 tar 명령어에 zxvf 옵션을 주어 입력하면 설치까지 완료된다. 

[root@localhost tmp]# tar zxvf apache-flume-1.9.0-bin.tar.gz 
apache-flume-1.9.0-bin/conf/
apache-flume-1.9.0-bin/bin/
...

 

(10) apache-flume-1.9.0-bin 디렉토리가 존재하므로 아파치 플럼이 설치되었음을 확인할 수 있다. 

[root@localhost tmp]# ls
apache-flume-1.9.0-bin  apache-flume-1.9.0-bin.tar.gz 

 

(11) 아파치 플럼이 설치된 디렉토리의 구성을 확인할 수 있다. 

[root@localhost tmp]# ls apache-flume-1.9.0-bin
CHANGELOG  LICENSE  README.md      bin   doap_Flume.rdf  lib
DEVNOTES   NOTICE   RELEASE-NOTES  conf  docs            tools

 

(12) 루트 디렉토리에서 opt 하위에 새 디렉토리를 생성한다.

      1.9.0 디렉토리 생성시 flume 디렉토리도 함께 생성될 수 있도록 -p 옵션을 추가한다. 

[root@localhost tmp]# mkdir -p /opt/flume/1.9.0

     * 리눅스의 opt 디렉토리는 윈도우의 Program Files 폴더와 비슷한 역할로 응용 프로그램이 위치하는 곳이다. 

     * 운영체제와 응용 프로그램들은 서로 분리시켜야 하는데,

       1) 운영체제 파일을 응용 프로그램 파일로 덮어쓰는 것을 방지하고,

       2) 응용 프로그램을 모듈화하여 추가, 삭제, 수정을 용이하게 하기 위함이다. 

     [ 참고 ] 리눅스 시스템의 디렉토리 구조와 기능

                https://firedev.tistory.com/entry/Linux-Unix-리눅스시스템-디렉토리-구조와-기능

 

(13) 디렉토리가 모두 만들어졌는지 확인한다. 

[root@localhost tmp]# ls /opt
flume  rh
[root@localhost tmp]# ls /opt/flume
1.9.0
[root@localhost tmp]# ls /opt/flume/1.9.0
[root@localhost tmp]# 

 

(14) 아파치 플럼의 모든 디렉토리와 파일을 새로 만든 1.9.0 디렉토리로 옮긴다. 

[root@localhost tmp]# mv apache-flume-1.9.0-bin/* /opt/flume/1.9.0/

 

(15) 빈 디렉토리가 된 apache-flume-1.9.0-bin 디렉토리와 압축파일을 삭제한다. 

[root@localhost tmp]# ls apache-flume-1.9.0-bin
[root@localhost tmp]# ls
apache-flume-1.9.0-bin  apache-flume-1.9.0-bin.tar.gz
[root@localhost tmp]# rm -rf apache-*
[root@localhost tmp]# ls
[root@localhost tmp]#

 

(16) install_flume.sh 파일을 만들 수 1.8.0 버전을 설치할 수도 있다. 

      # sh install_flume.sh 1.8.0

 

 

 

 

반응형

'교육과정 > KOSMO' 카테고리의 다른 글

Day64  (0) 2021.01.13
Day63  (0) 2021.01.12
Day61  (0) 2021.01.08
Day60  (0) 2021.01.07
Day59  (0) 2021.01.06