Shell Script 작성 전 알아두면 좋은것들

식빵·2022년 2월 26일
0

Shell Script

목록 보기
2/5
post-thumbnail

Shell script 작성을 위해서 직접적으로 필요한 것은 아니지만,
알아두면 이후에 Shell Script 작성 시 도움이 될만한 것들을 적어본다.


🍀 Bash의 종류


📌 Interactive Shell

사용자와 상호작용을 하는 쉘이다.


1. Login Shell

사용자로 부터 프롬프트를 통해 직접 명령을 입력받아 실행시키는 쉘이다.
초기에 아래와 몇가지 설정용 스크립트 파일이 동작한다.

  • 모든 로그인 사용자에게 적용되는 설정 : /etc/profile
  • 개별 로그인 사용자에게 적용되는 설정
    • ~/.bash_profile
    • ~/.bash_login
    • ~/.profile
    • 참고로 개별 설정은 위의 셋중 하나만 적용되며, 위로 갈수록 우선순위가 높다.

2. Non-Login Shell

로그인 후 Bash에 bash 라고 입력하여 새로 만들어지는 Child Shell을 의미한다.
Login Shell과는 달리 ~/.bashrc 스크립트 파일을 실행하여 기본 설정을 지정한다.

그런데 user를 생성하면 기본 ~/.profile 스크립트가 생성되는데,
이 스크립트 내에서 ~/.bashrc 스크립트를 실행함한다.
그래서 Login Shell은 실제로는 Non-Login Shell 의 설정도 같이 쓴다.



📌 Non-Interactive Shell

사용자와 상호작용 하지 않는 쉘이며,
스크립트 파일을 실행할 때 생성되는 subshell이 바로 이 쉘이다.
alias, history, job control 관련 명령어 (ex: fg, bg) 등의 Interactive Shell에서만
필요한 명령어들은 동작하지 않는다.





🍀 명령어의 종류와 우선순위

Shell 에서는 다양한 종류의 명령어가 쓰인다.
그리고 종류에 따라서 우선순위가 달라진다.
지금부터 우선순위가 높은 순부터 명령어의 종류를 작성해보겠다.


1. Alias

밑에서 보게될 명령어들에 별칭(alias)를 주면 해당 명령어는 Alias 명령어가 된다.

ex) alias ls='ls -alF'


2. Function

말그대로 함수다. 사용자는 원하면 함수를 만들고 일반적인 명령어처럼 쉘에서 쓸 수 있다.

ex)

[dailycode@myComp:~]$ function something { ls; }
[dailycode@myComp:~]$ something
lab  log.20220226

3. Built-in 명령어

Shell 자체에 내장된 명령어이다.

참고로 bash 쉘은 sh 쉘 보다 많은 내장 명령어를 제공한다.
그러니 쉘 스크립트를 짜고 나서, 스크립트를 실행할 쉘은 bash 쉘을 사용하는 게 좋다.


4. Keyword

for, while 등과 같이 이미 지정된 키워드를 의미한다.
이러한 키워드들은 사실 자기자신만 쓰면 동작하지 못한다.
그래서 이러한 키워드를 사용하는 명령어를 복합 명령어라고도 부른다.


5. 외부 명령

$PATH 경로상에 존재하는 명령으로 시스템 디렉토리에 위치한 명령어다.
참고로 $PATH: 를 구분자로 경로를 구별하는데, 앞에 있을 수록 우선순위가 높다.

ex)

# 보기 좋게 하기 위하여 $PATH 문자열에 있는 ":" 를 "\n"로 대체했다.
# 실제로는 "/usr/local/sbin:/usr/local/bin:/usr/sbin:..." 와 같은 모양새다.
[dailycode@myComp:lab]$ echo -e ${PATH//:/\\n} 
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin

# 아래에서 위로 갈수록 우선순위가 높다.
# 예를 들어서 /usr/bin/goodjob ,  /bin/goodjob 둘이 똑같은 이름의 명령어가 있다면
# /usr/bin/goodjob 가 우선순위가 높다는 뜻이다.



실습을 통해서 알아보기

type -a 명령어를 통해서 정말 위와 같은 우선순위가 동작하는 지 확인할 수 있다.


[dailycode@myComp:~]$ type -a pwd # 
pwd is a shell builtin
pwd is /usr/bin/pwd
pwd is /bin/pwd

[dailycode@myComp:~]$ function pwd { ls; } # 이러면 어떨까?
[dailycode@myComp:~]$ type -a pwd # 
pwd is a function
pwd ()
{
  ls --color=auto         # alias 가 우선순위가 더 높아서 alias가 적용된게 보인다.
}
pwd is a shell builtin
pwd is /usr/bin/pwd
pwd is /bin/pwd

[dailycode@myComp:~]$ alias pwd='echo hello'
[dailycode@myComp:~]$ pwd
hello

[dailycode@myComp:~]$ function pwd { ls; } # 이러면 어떨까?
[dailycode@myComp:~]$ type -a pwd # 
pwd is aliased to `echo hello'
pwd is a function
pwd ()
{
  ls --color=auto
}
pwd is a shell builtin
pwd is /usr/bin/pwd
pwd is /bin/pwd


############################ 참고 #############################
## 여태까지 한거 다 원복 시키려면?  다시 로그인하면 된다.

[dailycode@myComp:~]$ su - dailycode 

# 아니면 터미널을 다시 실행하고 로그인하는 방법도 있다.

tip: 명령어 별 도움말 보기

  • 외부 명령: man 명령어
  • 내장 명령: help 명령어
  • 명령어 유형 및 우선순위 : type -a 명령어





🍀 명령어 실행의 차이


📌 외부 명령어 실행 특징

외부 명령어는 실행하면 fork-and-exec 동작 구조를 갖는다.
forkexec는 모두 system call이고 각 특성은 아래와 같다.

  • fork: 현재 실행중인 프로세스와 똑같은 내용물 및 환경을 갖는 프로세스를 생성한다.
    새롭게 만들기 때문에 해당 프로세스는 fork를 호출한 프로세스와 다른 PID를 부여받는다.

  • exec: 프로세스 자기자신의 내용물을 다른 프로세스가 완전히 대체해버리는 것이다.
    자기자신의 내용물을 변경하는 것이여서 PID가 변경되지 않는다.

즉 Bash에서 외부 명령어를 실행하면 현재 Bash와 똑같은 환경을 갖는 Bash 프로세스(자식 프로세스)를 새롭게 띄우고, 그 프로세스에 실행되어야할 내용물을 외부 명령어의 실행 내용물로 대체하여 동작하는 것이다.

참고로 이 과정에서 부모 프로세스에 있던 환경변수를 copy해서 자식 프로세스에게 넘겨준다.

잘 이해가 안 가면 아래 Youtube 영상을 참조하자.


📌 내장 명령어 실행 특징

내장 명령어는 쉘 자체 내에 있는 것이기 때문에 따로 fork를 하지 않고 bash 자체의
프로세스 위에서 곧바로 실행된다.




🍀 Shebang

쉘 스크립트의 맨 윗줄에 적혀있는 #!/bin/bash 가 바로 Shebang이다.
쉘 스크립트를 실행하면 kernerl 에서 맨 처음 쉘 스크립트의 가장 첫 2바이트를
읽는데, 읽은 것이 #! 이면 이후에 적혀 있는 프로그램(여기서는 /bin/bash)으로
현재의 쉘 스크립트를 해석, 실행하도록 한다.

그래서 Shebang!#/bin/bash 로 한 ./shell_script.sh를 실행시키면,
실제로는 /bin/bash shell_script.sh 와 똑같은 동작을 하게 된다.



만약 안 적으면 어떻게 될까?
Shebang은 안 적어도 실행될 수도 있다. 하지만 여러 커뮤니티에서 말하지만
반드시 Shebang을 쓰라고 권장한다. 리눅스 배포판 마다 Shebang이 없을 시에
쉘 스크립트를 어떤 프로그램으로 돌릴지가 다를 수 있다고 한다!
확실히 하려면 꼭 적어두자.





🍀 Redirection

출력 전환, 입력 전환 등은 사실 Shell script가 아니여도 알아두면 좋다.
이와 관련된 좋은 글을 아래와 같이 링크를 달아 두겠다.

리다이렉션(Redirection)





✨ 참고

profile
백엔드를 계속 배우고 있는 개발자입니다 😊

0개의 댓글