Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
05-19 10:17
관리 메뉴

nomad-programmer

[Programming/Shell] 자주 사용하는 Shell 명령 및 문법 본문

Programming/Shell

[Programming/Shell] 자주 사용하는 Shell 명령 및 문법

scii 2020. 12. 14. 14:25

리눅스는 기본적인 쉘이 Bash (Bourne-again shell) 이다. bash 쉘에서 자주 사용하는 명령 및 문법을 알아보자.


> (출력 리다이렉션)

출력 리다이렉션. 명령 실행의 표준 출력(stdout)을 파일로 저장한다. 유닉스계열 운영체제는 장치도 파일로 처리하기 때문에 명령 실행 결과를 특정 장치로 보낼 수도 있다. 또한 파일이 없다면 새로운 파일을 생성하여 그곳에 출력하고 있다면 해당 파일의 내용을 완전히 덮어씌어 그곳에 출력한다.

$ echo "hello" > ./hello.txt
$ echo "hello" > /dev/null

>> (출력 리다이렉션 <추가>)

명령 실행의 표준 출력 (stdout)을 파일에 추가한다. > 는 이미 있는 파일에 내용을 덮어 쓰지만 >> 는 파일 뒷부분에 내용을 추가한다.

$ echo "world" >> ./hello.txt

< (입력 리다이렉션)

입력 리다이렉션이다. 파일의 내용을 읽어 명령의 표준 입력(stdin)으로 사용한다.

$ cat < ./hello.txt

<<< (입력 리다이렉션)

문자열을 명령 (프로세스)의 표준 입력으로 보낸다.

$ cat <<< "user name is ${USER}"

<< EOF (입력 리다이렉션)

여러 줄의 문자열을 명령 (프로세스)의 표준 입력으로 보낸다.

cat > ./hello.txt << EOF
Hello World
Host name is $(hostname)
User name is ${USER}
EOF

cat은 파일이나 표준 입력의 내용을 출력하는 명령이다. cat의 표준 출력을 ./hello.txt로 저장하고, <<EOF로 문자열을 cat의 표준 입력으로 보낸다. 이렇게 하면 문자열 3줄이 ./hello.txt 파일에 저장된다.


<< EOF >> (입/출력 리다이렉션)

여러 줄의 문자열을 명령 (프로세스)의 표준 입력으로 보낸다.

cat << EOF >> ~/.bashrc
# initialize
source ~/test_init.sh
EOF

결과적으로 두 줄이 bashrc 파일에 추가된다.


2> (표준 에러 리다이렉션)

명령 실행의 표준 에러 (stderr)를 파일로 저장한다.


2>> (표준 에러 리다이렉션 <추가>)

명령 실행의 표준 에러 (stderr)를 파일에 추가한다.


&> (표준 출력/표준 에러 리다이렉션)

표준 출력과 표준 에러를 모두 파일로 저장한다.


1>&2 (표준 출력 -> 표준 에러)

표준 출력을 표준 에러로 보낸다. 다음의 코드는 echo 명령으로 문자열을 표준 출력으로 출력했지만 표준 에러로 보냈기 때문에 변수에는 문자열이 들어가지 않는다.

$ hello=$(echo "Hello World" 1>&2)
$ echo $hello

2>&1 (표준 에러 -> 표준 출력)

표준 에러를 표준 출력으로 보낸다. abcd라는 명령은 없으므로 에러가 발생하지만 에러를 표준 출력으로 보낸 뒤 다시 /dev/null로 보냈기 때문에 아무것도 출력되지 않는다.

$ abcd > /dev/null 2>&1

| (파이프)

파이프. 명령 실행의 표준 출력을 다른 명령의 표준 입력으로 보낸다. 즉 첫 번째 명령의 출력 값을 두 번째 명령에서 처리한다.

$ ls -al | grep .txt

$ (쉘의 변수)

쉘의 변수이다. 값을 저장할 때는 $를 붙이지 않고, 변수를 가져다 쓸 때만 $를 붙인다.

$ hello="Hello World!"
$ echo ${hello}

$() (evaluation)

명령 실행 결과를 변수화한다. 명령 실행 결과를 변수에 저장하거나 다른 명령의 매개 변수로 넘겨줄 때 사용한다. 또는 문자열 안의 명령의 실행 결과를 넣을 때 사용한다.

$ docker rm $(docker ps -aq)
$ echo $(date)

`` (evaluation)

$()과 마찬가지로 명령 실행 결과를 변수화한다.

$ docker rm `docker ps -aq`
echo `date`

&& (AND)

한 줄에서 명령을 여러개 실행한다. 단 앞에 있는 명령이 에러 없이 실행되어야 뒤에 오는 명령이 실행된다.

$ make && make install

다음의 코드는 _tmp 라는 디렉토리가 존재하지 않으면 그 다음 명령인 mkdir 명령이 실행되어 _tmp 디렉토리가 생성된다.

$ [[ ! -d ~/_tmp ]] && mkdir ~/_tmp

|| (OR)

한 줄에서 첫 번째 명령이 거짓이면 그 다음 명령을 실행하고, 첫 번째 명령이 참이라면 그 다음 명령은 실행하지 않고 넘어갈 때 사용하면 된다.

다음의 코드는 _tmp 라는 디렉토리가 존재하면 그 다음 명령인 mkdir 명령이 실행되지 않는다. 하지만 _tmp 디렉토리가 없다면 그 다음의 명령이 실행되어 _tmp 디렉토리가 생성되는 코드이다.

$ [[ -d ~/_tmp ]] || mkdir ~/_tmp

; (한 줄에 명령 여러개 실행)

한 줄에서 명령을 여러 개 실행한다. 앞에 있는 명령이 실패해도 뒤에 오는 명령이 실행된다.

$ false; echo "Hello"; echo "World!"

' ' (문자열)

문자열이다. ' '안에 들어 있는 변수는 처리되지 않고 변수명 그대로 사용된다. 또한 ``와 $() 도 처리되지 않고 그대로 사용된다.

echo '$USER'

$USER 문자열 그대로가 출력된다.


" " (문자열)

문자열이다. 명령에 문자열 매개 변수를 입력하거나 변수에 저장할 때 주로 사용한다. ' '와는 달리 " "안에 변수가 들어 있으면 변수의 내용으로 바뀐다. 또한 ``와 $()도 실행 결과 값이 사용된다.

$ echo "Hello World!"
$ echo "$USER"
$ echo "Host name is $(hostname)"
$ echo "Time: `date`"

" ' ' " (문자열)

" " 안에 ' ' 가 들어갈 수 있다. 명령 안에서 다시 명령을 실행하고 매개 변수를 지정할 때 사용한다.

$ bash -c "/bin/echo Hello '${USER}'"

\ (이스케이프 문자)

' ' 안에서 "를 사용할 때는 \" 처럼 앞에 \를 붙여준다.

$ bash -c "/bin/echo '{ \"user\": \"$USER\" }'"

" " 안에서 ", $, ` 등의 특수 문자 그대로 사용하려면 앞에 \ 를 붙여준다.

$ echo "\$hello \" \`"

${} (변수 치환)

변수 치환(substitution) 이다. " " 문자열 안에서 변수를 출력할 때 주로 사용한다. ${} 대신 $ 만 사용해도 된다.

$ str="world"
$ echo "hello ${str}"

스크립트에서 변수의 기본 값을 설정할 때도 사용한다. 다음은 HELLO 변수가 있으면 그대로 사용하고 변수가 없으면 기본 값으로 설정한 abcd를 대입한다.

$ HELLO=
$ HELLO=${HELLO-"abcd"}
$ echo ${HELLO}

값이 NULL인 HELLO 변수가 이미 있기 때문에 기본 값을 대입하지 않는다.

다음은 변수에 값이 있으면 그대로 사용하고, 값이 NULL이면 기본 값으로 설정한 abcd를 대입한다.

$ WORLD=
$ WORLD=${WORLD:-"abcd"}
$ echo ${WORLD}

변수에 값이 NULL이므로 기본 값을 대입한다.


\ (여러 줄 표현)

한 줄로된 명령을 여러 줄로 표현할 때 사용한다.

$ docker container run -d --name hello busybox:latest
$ docker container run \
    -d
    --name hello \
    busybox:latest

{1..10} (연속된 숫자)

연속된 숫자를 표현한다. {시작 숫자..끝 숫자} 형식이다.

$ echo {1..10}

{문자열1,문자열2}

{ } 안에 문자열을 여러 개 지정하여 명령 실행 횟수를 줄인다. 다음은 hello.txt, world.txt 두 파일을 한 번에 hello-dir 디렉토리 아래에 복사한다.

$ cp ./{hello.txt,world.txt} hello-dir/

if (조건문)

if 조건문이다. 변수와 변수끼리 또는 문자열을 비교할 때 사용한다.

if [$a -eq $b ]; then
    echo $a
fi

숫자 비교

  • -eq (==) : 같다
  • -ne (!=) : 같지 않다
  • -gt (>) : 초과
  • -ge (>=) : 이상
  • -lt (<) : 미만
  • -le (<=) : 이하

문자열 비교

  • =, == : 같다
  • != : 같지 않다
  • -z : 문자열이 NULL일 때
  • -n : 문자열이 NULL이 아닐 때

for (반복문)

for 반복문이다. 변수 안에 있는 값을 반복하거나 범위를 지정하여 반복할 수 있다

for i in $(ls)
do
    echo $i
done

// ---------------------------------

for (( i=0; i<10; i++ ))
do
    echo $i
done

// ---------------------------------

NUM=(1,2,3)
for i in ${NUM[@]}
do
    echo $i
done

while (반복문)

while 반복문이다.

while true:
do
    echo "Hello World!";
    sleep 1;
done

export (환경 변수 만듦)

설정한 값을 환경 변수로 만든다. export <변수>=<값> 형식이다.

$ export HELLO="WORLD"

printf (형식지정 출력 함수)

지정한 형식대로 값을 출력한다. 파이프와 연동하여 명령 (프로세스)에 값을 입력하는 효과를 낼 수 있다.

$ printf 80\\nexampluser\\ny | example-config

// 결과
Port: 80
User: exampleuser
Save Configuration (y/n): y

예를 들어 example-config는 Port, User, Save Configuretion을 사용자에게 입력을 받는다. printf로 미리 값을 설정하여 파이프로 example-config에 넘겨주면 사용자가 입력하지 않아도 자동으로 값이 입력된다. 줄바꿈(개행)은 \\n 으로 표현한다.


sed (문자열 치환)

텍스트 파일에서 문자열을 변경한다. hello.txt 파일의 내용 중에서 hello라는 문자열을 찾아 world 문자열로 바꾸려면 다음과 같이 실행한다.

$ sed -i "s/hello/world/g" hello.txt

sed -i "s/<찾을 문자열><바꿀 문자열>/g" <파일명> 형식이다. /와 같은 특수 문자는 앞에 \를 붙여 \/로 입력한다.


# (주석)

주석이다. 스크립트에 설명을 추가하거나, 명령이 실행되지 않도록 한다.

# echo "hi!"
Comments