정보

    • 업무명     : 쉘 스크립트 사용법 (배열을 사용하는 법)

    • 작성자     : 박진만

    • 작성일     : 2020-07-18

    • 설   명      :

    • 수정이력 :

     

     내용

    [특징]

    • 쉘 스크립트를 사용할 때의 유용한 팁 모음

     

    [활용 자료]

    • 없음

     

    [자료 처리 방안 및 활용 분석 기법]

    • 없음

     

    [사용법]

    • 작업 환경 구축

    • 소스 코드 작성 및 실행

    • 실행 결과 확인

     

    [사용 OS]

    • Linux (CentOS v7.0)

    • VMware Workstation Pro v15.5

     

    [사용 언어]

    • Bash Script

     

     소스 코드

    [배열 사용법]

    [배열에 값을 설정]

    변수=(값1 값2 값3)

    → 값 목록에서 변수를 초기화한다.

    • 괄호 안에 값의 목록을 제공 한 변수로 설정하여 그 변수를 배열로 사용할 수있다.

    • ※ ksh의 경우 set 명령을 사용하여 배열 설정한다. 괄호를 사용하여 설정 방법은 사용하지 못할 수도 있으므로, ksh에서 배열을 사용하려면 set 명령을 사용한다.

    $ array=(111 "foo" 222 "bar" 333 "foobar")
    # ↑ 배열에 값을 설정한다.
    
    $ echo $array
    111
    # ↑ 인덱스를 지정하지 않으면 첫 번째 값만 출력된다.
    
    $ echo ${array[@]}
    111 foo 222 bar 333 foobar
    # ↑ 모든 값을 출력하는 경우 인덱스에 "@"를 지정한다.
    • ksh의 경우 다음과 같이 set 명령을 사용한다.

    $ set -A array 111 "foo" 222 "bar" 333 "foobar"
     ↑ ksh의 경우 set 명령에 -A 옵션을 지정한 다음, 매개 변수 값 목록을 지정한다.
     
    $ echo $array
    111
    $ echo ${array[@]}
    111 foo 222 bar 333 foobar
    • 괄호 안에 값을 직접 지정 이외에도 변수의 값이나 역 따옴표를 사용하여 명령의 실행 결과를 지정하는 것도 가능하다.

    $ date
    2020년  7월 17일 금요일 12:00:00 KST
    $ array=(`date`)
    $ echo ${array[3]}
    금요일
    # ↑ date 명령의 실행 결과를 배열로 변수 array로 설정되어있다.
    $ VAR="hoge fuga foo bar"
    $ array=($VAR)
    $ echo ${array[3]}
    bar
    # ↑ 변수 VAR에 설정되어 있던 값이 배열로 변수 array로 설정되어있다.

     

    [배열의 각 요소에 값을 설정]

    배열 이름 [인덱스] = 값
    

    → 배열의 값을 개별적으로 설정하는 경우 인덱스를 지정할 필요가있다.

    • 배열에 인덱스를 지정하는 것으로, 배열의 각 요소에 개별적으로 값을 설정할 수있다. 또한 괄호를 사용하여 배열에 설정 한 각 값은 선언 된 순서대로 배열 인덱스 0,1,2, ..., n에 저장된다.

    • 즉, array=("foo" "bar")선언 된 경우 다음과 같이 설정 한 경우와 동일한 결과가된다.

      • array[0]="foo"

      • array[1]="bar"

    • 인덱스로 지정 가능한 값은 숫자만으로 임의의 문자열을 지정할 수 없다 . 즉 연관 배열을 사용할 수 없다. 사용하여도 에러가되지 않지만, 의도한대로 움직이지는 않는다.

     

    [배열에 요소를 추가]

    [단일 요소를 추가]

    배열이름+=(값)

    → 추가 할 값을 ()로 둘러싸고 배열 해지고 +=배열에 추가한다.

    • 추가 할 요소를 ()이지 배열 화하면서 추가 대상 배열에 가산하여 요소를 추가 할 수 있다.

    $ array=("hoge" "fuga" "foo" "bar")
    $ echo "${array[0]}, ${array[1]}, ${array[2]}, ${array[3]}, ${array[4]}"
    hoge, fuga, foo, bar,
    # ↑ 추가 대상 배열 (5 번째 요소가 없는 상태).
    
    $ array+=("end")
    # ↑ 5 번째 요소를 추가한다.
    
    $ echo "${array[0]}, ${array[1]}, ${array[2]}, ${array[3]}, ${array[4]}"
    hoge, fuga, foo, bar, end
    # ↑ 5 번째 요소가 추가되어있다.
    

     

    [여러 요소 추가]

    배열이름+=(값 1 값 2 값 3)

    → 여러 값을 한 번에 추가하는 경우도 하나의 경우와 마찬가지로 ()이지 배열 화하면서 추가 할 요소를 공백으로 구분 나란히 가산한다.

    $ array=("hoge" "fuga" "foo" "bar")
    $ echo "${array[0]}, ${array[1]}, ${array[2]}, ${array[3]}, ${array[4]}, ${array[5]}"
    hoge, fuga, foo, bar, ,
    # ↑ 추가 대상 배열 (5 번째, 6 번째 요소 없는 상태).
    
    $ array+=("123" "456")
    # ↑ 2 가지 요소를 한 번에 추가한다.
    
    $ echo "${array[0]}, ${array[1]}, ${array[2]}, ${array[3]}, ${array[4]}, ${array[5]}"
    hoge, fuga, foo, bar, 123, 456
    # ↑ 5 번째, 6 번째의 요소가 추가되어있다.
    
    • 2 개 이상의 요소를 한 번에 추가 할 경우에도 마찬가지로 ()으로 할 수 있다.

     

    [변수의 값을 요소로 추가]

    배열이름+=($변수이름)

    → 변수의 값을 배열의 요소로 추가한다.

    • 문자열이나 숫자를 지정하는 것과 마찬가지로 변수의 값도 추가 가능하다. 변수의 값이 공백으로 구분 된 문자열 인 경우 여러 요소로 구성되는 경우가 있기 때문에 주의가 필요하다. 즉 하나의 요소로 배열에 추가하려면 변수를 ""로 둘러싸싸야 한다.

    $ array=("hoge" "fuga" "foo" "bar")
    $ echo "${array[0]}, ${array[1]}, ${array[2]}, ${array[3]}, ${array[4]}, ${array[5]}"
    hoge, fuga, foo, bar, ,
    $ element="123 456"
    # ↑ 요소로 추가 할 변수를 만들 수 있다.
    
    $ array+=("$element")
    # ↑ "" ""로 묶어 변수의 값을 하나의 요소로 추가한다.
    
    $ echo "${array[0]}, ${array[1]}, ${array[2]}, ${array[3]}, ${array[4]}, ${array[5]}"
    hoge, fuga, foo, bar, 123 456,
    # ↑ 변수의 값이 5 번째 요소로 추가하고있다.
    
    • 다음은 ""로 구분되지 않은 경우의 결과를 본다.
    $ array=("hoge" "fuga" "foo" "bar")
    $ echo "${array[0]}, ${array[1]}, ${array[2]}, ${array[3]}, ${array[4]}, ${array[5]}"
    hoge, fuga, foo, bar, ,
    $ element="123 456"
    $ array+=($element)
    # ↑ "" ""로 묶여있지 않고 변수의 값을 추가한다.
    $ echo "${array[0]}, ${array[1]}, ${array[2]}, ${array[3]}, ${array[4]}, ${array[5]}"
    hoge, fuga, foo, bar, 123, 456
    # ↑ 변수의 값이 5 번째와 6 번째 요소로 추가하고있다.
    
    • 변수가 확장 된 상태 가 ""로 묶으면 array+=("123 456")이웃, ""로 구분되지 않은 경우 array+=(123 456)가되기 때문에 당연한 결과이지만 쉘 스크립트의 경험이 적은 사람은 간과이므로주의 할 것.

    • 반대로 이것을 이용하여 공백으로 구분하여 설정된 변수 값을 여러 요소로 배열에 추가 할 수도 있다 .

    • 미세한 차이로 결과가 크게 다르기 때문에 알기 힘든 사람도 있겠지만,이 배열의 경우에 한정하지 않고, 쉘 스크립트 변수 배포 한 후 최종적으로 어떤 형태로 명령이 실행되는지 를 이미지로 만들어 하는 것이 능숙의 지름길이다.

    • 이번 같은 ""여부에 따른 동작의 차이에 대해서도 변수 확장 후 어떤 명령이 있는지를 이미지하면 바로 결과를 상상할 수 있을 것이다.

    • 배열에 요소를 추가하는 방법은

    1. 추가 대상 배열의 모든 요소와 추가 할 값을 배열 화 다시 설정하는 방법 (eg array=("${array[@]}" "hoge"))과
    2. 현재의 요소 수에서 배열 끝의 인덱스를 구하고, 거기에 추가 할 요소를 설정하는 방법 (eg array[${#array[@]}]="hoge")
    • 가 있지만, 이러한 방법이라고 추가 대상 배열의 인덱스가 불연속 인 경우에 문제가 발생할 .

    • 추가 대상 배열의 모든 요소와 추가 할 값을 배열 화하고 재설정하는 방법으로 요소를 추가 해 본다.

    $ array[0]="000"
    $ array[2]="222"
    $ array[5]="555"
    $ echo "${array[0]}, ${array[1]}, ${array[2]}, ${array[3]}, ${array[4]}, ${array[5]}, ${array[6]}"
    000, , 222, , , 555,
    # ↑ 인덱스가 불연속적인 배열을 생성한다.
    
    $ array=("${array[@]}" "end")
    # ↑ 모든 요소와 추가 할 값을 배열 화하여 설정한다.
    
    $ echo "${array[0]}, ${array[1]}, ${array[2]}, ${array[3]}, ${array[4]}, ${array[5]}, ${array[6]}"
    000, 222, 555, end, , ,
    # ↑ 불연속이었던 인덱스가 얀속적인 것으로 변화하였다.
    
    • 이 방법은 배열 요소의 추가가 아니라 엄밀하게는 배열의 재 작성 될 때문에 당연히 불연속이었다 인덱스 다시 작성되고 정상적으로 0에서 연속이다.

    • 다음 현재 요소 수의 배열 끝의 인덱스를 구하고, 거기에 추가 할 요소를 설정하는 방법에 요소를 추가 해 본다.

    $ array[0]="000"
    $ array[2]="222"
    $ array[5]="555"
    $ echo "${array[0]}, ${array[1]}, ${array[2]}, ${array[3]}, ${array[4]}, ${array[5]}, ${array[6]}"
    000, , 222, , , 555,
    # ↑ 인덱스가 불연속적인 배열을 생성한다.
    
    $ array[${#array[@]}]="end"
    # ↑ 요소 수를 인덱스로 지정하고 추가 할 요소를 설정한다.
    
    $ echo "${array[0]}, ${array[1]}, ${array[2]}, ${array[3]}, ${array[4]}, ${array[5]}, ${array[6]}"
    000, , 222, end, , 555,
    # ↑ 배열의 끝이 아니라 세 번째 요소로 구성되어있다.
    
    • 배열의 인덱스가 연속하고있는 경우는 배열의 "요소 수 = 말미 (마지막 요소의 다음) 인덱스 '가되지만, 인덱스가 불연속이면 당연히 이것은 성립되지 않는다.

    • 위의 예에서도 요소가 세 개이기 위하여 array[3]="end"실행되어 인덱스가 3, 즉 네 번째 요소로 구성되어있다.

    • += 를 사용하여 요소를 추가하여이 문제를 해결할 수 있다.

    $ array[0]="000"; array[2]="222"; array[5]="555"
    $ echo "${array[0]}, ${array[1]}, ${array[2]}, ${array[3]}, ${array[4]}, ${array[5]}, ${array[6]}"
    000, , 222, , , 555,
    #↑# ↑ 인덱스가 불연속적인 배열을 생성한다.
    
    $ array+=("end")
    # ↑ "+ ="배열에 요소를 추가한다.
    
    $ echo "${array[0]}, ${array[1]}, ${array[2]}, ${array[3]}, ${array[4]}, ${array[5]}, ${array[6]}"
    000, , 222, , , 555, end
    # ↑ 인덱스가 불연속인 경우에도 배열 끝에 추가되어있다.
    
    • 배열에 요소를 추가하려면 '+ ='를 사용하는 것이 좋다.

    • 또한 +=를 사용하는 경우, 추가 할 값을 ()이지 배열 화하는 것을 잊지 마십시오. 다음과 같이 ()으로 배열화하지 않고 추가하면 첫 번째 요소에 문자열로 추가되는만큼 추가되기 때문에 주의가 필요하다.

    $ array=("hoge" "fuga" "foo" "bar")
    $ echo "${array[0]}, ${array[1]}, ${array[2]}, ${array[3]}, ${array[4]}"
    hoge, fuga, foo, bar,
    $ array+="end"
    # ↑ 배열 화하지 않고 추가한다.
    
    $ echo "${array[0]}, ${array[1]}, ${array[2]}, ${array[3]}, ${array[4]}"
    hogeend, fuga, foo, bar,
    # ↑ 선두의 요소 값의 끝에 추가되어있다.
    

     

    [배열의 요소를 참조]

    [각 요소 참조]

    $ {배열이름[인덱스]}
    

    → 배열에 인덱스를 지정하면 각 요소의 값만을 참조 할 수있다.

    • 배열의 참조 방법은 변수처럼 $를 사용하지만, 반드시 인덱스 부분을 포함한 변수 이름 전체 {}로 묶어야 한다.

    $ date
    2020년  7월 17일 금요일 12:25:04 KST
    $ array=(`date`)
    $ echo ${array[0]}
    2020년
    # ↑ 인덱스 부분을 포함하여 {}로 둘러싼 다.
    
    $ index=3
    $ echo ${array[$index]}
    금요일
    # ↑ 인덱스는 변수를 지정할 수도 있다.
    
    $ echo $array
    2020년
    # ↑ 인덱스를 지정하지 않으면 첫 번째 값이 참조된다.
    
    $ echo $array[3]
    2020년[3]
    # ↑ 인덱스를 지정하는 경우 {}를 생략하면 제대로 볼 수 없다.
    

     

    [모든 요소 ​​참조]

    • 배열에 설정되어있는 모든 값을 한 번에 볼 수 있다.

    ${배열이름[@]}

    → 인덱스 @를 지정하여 배열의 모든 값이 공백으로 구분하여 출력된다.

    • 덧붙여서 @이외에도 *이 가능하다. 이 둘의 차이는 앞서 언급되어있는 $@과 $*의 차이와 같다.
    $ array=("foo" "bar" "hoge" "fuga" "HOGE HOGE" "FUGA FUGA")
    $ echo ${array[@]}
    foo bar hoge fuga HOGE HOGE FUGA FUGA
    # ↑ 인덱스에 "@"를 지정했기 때문에 배열의 모든 요소 값이 공백으로 구분하여 출력되고있다.
    
    $ for i in "${array[@]}"
    > do
    >   echo $i
    > done
    foo
    bar
    hoge
    fuga
    HOGE HOGE
    FUGA FUGA
    
    $ for i in "${array[*]}"
    > do
    >   echo $i
    > done
    foo bar hoge fuga HOGE HOGE FUGA FUGA
    • 인덱스 @를 사용하여 배열의 참조는 for 문을 사용하는 경우에 매우 편리하다. 다음은 그 예 (atmark.sh).

    #!/bin/bash
    
    # 현재 디렉토리의 파일 이름 목록을 배열에 저장
    files=(`ls -1`)
    
    # 인덱스에 @를 지정하여 모든 요소를 for 문에 값 목록에 지정
    for file in ${files[@]}
    do
      # 각 파일의 파일 크기
      size=`ls -l $file | awk '{print $5}'`
    
      echo "FILE: $file - $size byte"
    done
    
    exit 0

     

    • 이 쉘 스크립트 atmark.sh의 실행 결과는 다음과 같다

    $ ./atmark.sh
    FILE: atmark.sh - 372 byte
    FILE: file1 - 165 byte
    FILE: file2 - 531 byte
    FILE: file3 - 655 byte
    FILE: file4 - 1454 byte
    FILE: file5 - 541 byte
    • 각 요소에 대한 처리를 할 경우에는 for 문 목록에 인덱스에 '@'를 지정한 배열을 지정하면 foreach 문 같은 처리를 쉽게 설명 할 수있다.

     

    [배열의 요소를 참조2]

    $ {#배열이름[*]}
    

    → 배열 이름 앞에 #으로 전체 배열 (인덱스로 *지정)를 참조한다.

    • 변수 이름 #을 부가 한 참조는 변수의 설정 값의 문자에 열기 있지만, 배열 이름 (정확하게는 배열 이름 [*])에 #를 추가하여 참조하면 배열의 전체 요소 수에 전개된다.

    $ array=("foo" "bar" "hoge" "fuga" "HOGE HOGE" "FUGA FUGA")
    $ echo "${#array[*]}"
    6
    $ echo "${#array[@]}"
    6
    # ↑ 인덱스에 "@"를 지정하여도 결과는 같다.
    

     

    [배열의 요소 반복]

    for i in "${array[@]}"
    do
      ...
    done

    → for 문장에 큰 따옴표로 묶 인덱스 @를 지정하는 배열을 전달한다.

    • 배열의 모든 요소에 대해 작업을 수행하려는 경우에 배열의 요소에서 루프를 실시하고 싶은 경우는 for 문 루프 대상으로 큰 따옴표로 묶 인덱스 @를 지정하는 배열을 전달합니다.

    • 주의 할 점은 두 가지.

    1. 요소에 공백이 포함 된 것을 고려하고 큰 따옴표로 묶기
    2. *대신 @을 사용 해야 함
    • 요소에 공백이 들어 있지 않은 것을 보증 할 수 있다면 큰 따옴표를 사용할 필요없이 *와 @의 구별도 필요하지 않지만, 모범 사례로 배열 루프 처리를 할 경우 큰 따옴표와 @를 사용하면 기억하기 원한다 .

    • 덧붙여서, 더블 쿼트와 *를 사용하면 쉘이 배열 전체를 하나의 값으로 전개하기 때문에 요소가 몇개 있으려고도 루프가 한 번에 종료 해 버린다.

    $ # 「*」を使用してしまったダメな例
    $ array=(1 2 3 4 5)
    $ for i in "${array[*]}"
    > do
    >  echo "[${i}]"
    > done
    [1 2 3 4 5]
    # ↑ 요소가 5 개 있지만, 루프가 한번에 종료되어었음.
    
    $ # "@"를 사용한 올바른 예
    $ array=(1 2 3 4 5)
    $ for i in "${array[@]}"
    > do
    >  echo "[${i}]"
    > done
    [1]
    [2]
    [3]
    [4]
    [5]
    # ↑ 각 요소의 루프가 실행된다.
    
    • 인덱스 @를 지정하는 것으로, 쉘 for i in "1" "2" "3" "4" "5"해석하고 요소 몇분의 루프 처리를 할 수있다.

    • 또한 큰 따옴표를 사용하지 않으면 *및 @중 어느 것을 사용해도 결과는 동일하지만 다음과 같은 요소에 공백이있는 경우에 문제가 발생한다.

    # 배열의 요소가 공간을 포함하는 경우 (큰 따옴표를 사용하지 않음)
    $ array=(1 2 3 4 5 "6 6")
    $ for i in ${array[*]}
    > do
    >   echo "[${i}]"
    > done
    [1]
    [2]
    [3]
    [4]
    [5]
    [6]
    [6]
    # ↑ "6 6"이 큰 따옴표가 없기 때문에 2 개의 요소로 해석되기 때문에 반복 횟수가 1 회 많아지고있다.
    
    $ for i in ${array[@]}
    > do
    >   echo "[${i}]"
    > done
    [1]
    [2]
    [3]
    [4]
    [5]
    [6]
    [6]
    # ↑ "6 6"이 큰 따옴표가 없기 때문에 2 개의 요소로 해석되기 때문에 반복 횟수가 1 회 많아지고있다.
    
    • 큰 따옴표를 사용하지 않으면 쉘 for i in 1 2 3 4 5 6 6해석한다. 따라서 요소 "6 6"을 2 개의 요소로 간주되어 버린다.

    • 이러한 문제를 피하기 위해 반복되는데, 모범 사례로 배열 루프 처리를 할 경우 큰 따옴표와 @를 사용하는 것.

    $ array=(1 2 3 4 5 "6 6")
    $ for i in "${array[@]}"
    > do
    >   echo "[${i}]"
    > done
    [1]
    [2]
    [3]
    [4]
    [5]
    [6 6]
    # ↑ 큰 따옴표와 '@'을 사용하여 공간을 포함한 요소에도 대응 가능.
    

     

    [배열의 요소를 정렬]

    • 문자열로 정렬

    _IFS="$IFS"; IFS="\n"; array=(`for item in "${array[@]}"; do echo "$item"; done | sort`); IFS="$_IFS"
    

    → 배열의 모든 요소를 ​​출력 한 후 sort 명령에서 정렬을 실행하고 실행 결과를 다시 배열에 저장한다.

    • 배열의 요소에 공백이 포함 된 경우를 고려하여 사전에 IFS줄 바꿈 만 변경하여 둔다. 이렇게두면 정렬 결과의 배열에 재구성하는 동안 공백으로 구분 요소가 설정되는 것을 방지한다. 변경된 IFS마지막으로 취소합니다.

    • 배열은 for 문에 "${array[@]}"처럼 모든 요소를 의미하는 @사용 큰 따옴표로 묶인에 지정한다. 이 지정은 각 요소가 큰 따옴표로 둘러싸인 상태로 배열이 전개된다.

    • 즉, for 문에서 사용되는 변수 item에 배열 (요소의 공백 구분 단위가 아닌) 각 요소 단위로 값이 대입된다.

    • 또한 각 요소별로 echo를 출력함으로써 모든 요소가 줄 바꿈으로 구분하여 출력되므로 sort 명령으로 정렬이 가능하게된다.

    • 정렬 된 모든 요소를 줄 바꿈으로 구분하여 다시 배열로 설정하면 배열의 모든 요소를 정렬 할 수있게된다. 배열에 다시 설정 될 때 IFS이 줄 바꿈 만되어 있지 않은 경우, 줄 바꿈과 공백으로 구분하여 배열에 다시 설정되는 것이기 때문에 사전에 IFS줄 바꿈 만 변경하는 것이 필요하지만있다. 먼저 IFS변경하고있는 것은 그 때문이다.

    $ array=("222 222" "ccc ccc" "aaa aaa" "111 111" "bbb bbb" "333 333")
    # ↑ 테스트의 배열을 생성한다.
    
    $ for item in "${array[@]}"
    > do
    >   echo $item
    > done
    222 222
    ccc ccc
    aaa aaa
    111 111
    bbb bbb
    333 333
    # ↑ 모든 요소는 상기와 같이 (줄 바꿈으로 구분하여 출력).
    
    _IFS="$IFS";IFS="\n";array=(`for item in "${array[@]}"; do echo "$item"; done | sort`);IFS="$_IFS"
    # ↑ 사전 IFS를 줄 만 변경하고 정렬 된 출력을 배열에 다시 설정한다.
    
    $ for item in "${array[@]}"; do echo "$item"; done
    111 111
    222 222
    333 333
    aaa aaa
    bbb bbb
    ccc ccc
    # ↑ 실행 후 배열은 정렬 된 값이 설정되어있다.
    

     

    • 숫자로 정렬

    • 요소를 문자열이 아닌 숫자로 정렬하려면 sort 명령에 -n옵션을 지정한다.

    array=(`for item in "${array[@]}"; do echo "$item"; done | sort -n`)
    

    → -n옵션을 지정하고 숫자로 정렬 한 후 배열에 저장한다.

    • 배열의 요소가 수치 뿐이다 경우에는 공백을 포함하는 것을 상정하지 않으므로 IFS를 변경할 필요가 없다.

    $ array=(2 3 04 000 001)
    
    $ for item in "${array[@]}"; do echo "$item"; done
    2
    3
    04
    000
    001
    
    $ for item in "${array[@]}"; do echo "$item"; done | sort
    000
    001
    04
    2
    3
    
    $ for item in "${array[@]}"; do echo "$item"; done | sort -n
    000
    001
    2
    3
    04
    
    $ array=(`for item in "${array[@]}"; do echo "$item"; done | sort -n`)
    
    $ for item in "${array[@]}"; do echo "$item"; done
    000
    001
    2
    3
    04
    

     

     참고 문헌

    [논문]

    • 없음

    [보고서]

    • 없음

    [URL]

    • 없음

     

     문의사항

    [기상학/프로그래밍 언어]

    • sangho.lee.1990@gmail.com

    [해양학/천문학/빅데이터]

    • saimang0804@gmail.com

    본 블로그는 파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있음

     

    • 네이버 블러그 공유하기
    • 네이버 밴드에 공유하기
    • 페이스북 공유하기
    • 카카오스토리 공유하기