리눅스 - 쉘 기본 사용법 (입출력 재지정, 대치 등)
쉘이란
쉘은 쉘 프롬프트라고도 부르며, 리눅스에서 사용되는 명령어 처리기이다. 터미널이라고 생각하면 쉽다. 주로 명령어 처리, 시작 파일 실행, 스크립트 (프로그래밍) 기능을 수행한다. bourne 선생님께서 만든 '본 쉘'이 최초 버전이며, 현재는 이를 확장한 Bourne Again SHell, bash 쉘이 널리 사용된다.
로그인 쉘 : 시스템에 로그인할 때 실행되는 쉘, 꼭 bash가 아닐 수도 있으며 보통 계정 생성할 때 시스템 관리자가 결정한다. /etc/passwd 파일에서 확인할 수 있다.
시작 파일
쉘이 시작될 때 실행되는 파일이다. 시스템 시작 파일과 사용자 시작 파일 두 가지가 있으며, 각각 사용자 전체의 환경과 사용자 개개인의 환경을 설정하는 데 쓰인다. 아래 설명은 Bash 쉘 기준이다.
>> 시스템 : 시스템 내 모든 사용자에게 공통적인 속성을 설정한다(ex) 명령어 경로 설정). /etc/profile과 /etc/bashrc 가 있다. 즉 모든 사용자가 공유하는, 루트 아래 etc 디렉토리에 위치한다.
>> 사용자 : 개별 사용자에게만 적용되는 속성을 정한다 (ex) 홈 디렉토리 경로 설정). 사용자마다 서로 다른 시작파일을 사용하므로 홈 디렉토리 ~에 위치한다. ~/.bash_profile (또는 ~/profile), ~/bashrc 파일이 있다.
위에 설명한 4개의 파일 중 profile 파일은 환경변수를 정의하며, bashrc 파일은 별명(alias)과 함수를 정의한다.
>> 환경변수 : 쉘에서 변수는 지역변수와 환경변수로 나뉜다. 쉘이 어떤 프로그램을 실행하려면 자식 쉘을 생성해야 하는데, 이 때 부모 쉘(현재 쉘)에서 선언된 모든 변수를 전승받는다. 그러나 자식 쉘에서 지역변수는 이름만 존재할 뿐 값이 초기화되고, 환경변수는 자식 쉘에서도 값이 유지된다는 차이가 있다.
시작 파일은 최상위 쉘에서 실행되므로, profile에서 환경변수를 정의하면 해당 변수는 모든 쉘에서 동일한 값을 가질 수 있다. 이러한 환경변수에는 SHELL (쉘 종류), TERM (터미널 종류), USER (사용자명) PATH (명령어 실행 파일이 위치한 디렉토리들) 등이 있다. PATH는 프로그래머가 접근해 조작해야 할 경우도 있는 중요한 환경변수이다. 현재 정의된 환경변수를 확인하려면 env 명령어를 사용한다.
>> 별명 : C언어로 비유하자면 #define 같은 매크로 정의이다. alias 명령어로 실행하는데, 예를 들어 alias rm='rm -i'라고 하면 앞으로는 rm만 입력해도 rm -i를 실행한 결과를 갖게 된다.
시작파일은 또한 각 시작파일 내부에서 다음 시작파일의 존재 여부를 확인한 뒤 그 파일을 실행한다. 4개의 시작 파일이 실행되는 순서는 다음과 같다.
/etc/profile → ~/.bash_profile → ~/bashrc → /etc/bashrc → 쉘 시작
전면 처리, 후면 처리
>> 전면 처리 : 일반적인 명령어 수행은 전면 처리에 해당한다. 쉘이 직접 케어하는 명령어라고 생각하면 된다. 필요 시 입출력이 가능하며, 쉘은 전면 처리 명령어가 수행될 때까지 대기한다.
>> 후면 처리 : 후면 처리는 입력할 명령어 뒤에 &를 붙여서 실행할 수 있으며, 명령어가 실행되기는 하지만 이를 대기하지는 않는다. 후면 처리 실행 시, 명령어로 실행되는 프로세스의 작업 번호와 프로세스 번호를 출력한다. 은행에서 번호표를 뽑는 것과 비슷하다.
jobs 명령어를 통해 현재 후면 처리 중인 프로세스를 확인할 수 있고, %작업번호 인자를 같이 입력하면 해당 번호의 명령만 확인할 수 있다. fg %작업번호 명령어는 후면 처리 중인 해당 작업 번호의 프로세스를 전면 처리로 바꿔 실행한다.
입출력 재지정
개념은 간단하다. 입력과 출력을 터미널(모니터)이 아닌 다른 위치(주로 파일)에서 처리하도록 '위치'를 재지정하는 것이다>> 명령어 > 파일명 : 출력 재지정. 원래 터미널에 출력돼야 할 내용을 해당 파일에 대신 출력한다. 따라서 출력할 내용이 있는 명령어에서 사용하며, 파일에 원래 내용이 있으면 덮어쓰기 된다.
>> 명령어 2> 파일명 : 오류 재지정. 터미널에 출력될 오류 내역을 파일에 대신 출력한다. 표준 출력 stdout과 표준 오류 stderr는 엄연히 다른 출력이다.
>> 명령어 >> 파일명 : 출력 추가. 재지정과 비슷한 역할을 수행하지만 원래 내용을 덮어쓰지 않고 뒤에 추가된다.
>> 명령어 < 파일 : 입력 재지정. 원래 터미널에서 입력받아야 할 내용을 파일에서 대신 입력받는다. 따라서 입력받을 인자가 필요한 명령어에서 사용한다.
>> 명령어1 | 명령어2 : 파이프. 명령어1의 출력을 명령어2의 입력으로 전달한다. 입력, 출력 재지정의 간소화라고 생각해도 된다. who | wc -l 라고 입력할 경우를 예로 들어보자. who에서 현재 시스템에 접속중인 사람의 정보를 줄마다 출력하는데, 이를 터미널에 출력하는 대신 wc가 그 내역을 입력으로 받는다. wc -l은 줄 수를 세므로 이 명령어는 접속중인 사람의 수를 출력하는 기능을 수행한다.
여러 명령어 실행
>> 명령어 열 : 여러 명령어를 세미콜론 ; 을 사용해 한 줄로 연결한다. 각 명령어를 순차적으로 실행한다.
>> 명령어 그룹 : 그룹화 할 구간을 괄호 ()로 감싼다. 그룹 내 명령어도 열과 마찬가지로 순차적으로 실행되지만, 입출력을 공유한다는 점이 명령어 열과의 차이이다.
예를 들어 명령어1 ; 명령어2 > 파일명 이라는 문장은 명령어 2의 출력만 파일에 작성하지만, 그룹으로 묶은 (명령어1 ; 명령어2) > 파일명은 그룹이 출력을 공유하므로 명령어 1, 2의 출력 모두 파일에 작성한다.
>> 조건 명령어 열 : 쉘 명령어를 실행하면 그 결과는 참(실행 성공), 거짓 (실행 실패, 오류)의 논리값을 갖는다. 조건 명령어 열에서는 이 논리값에 대해 논리곱 &&, 논리합 || 2가지를 연산자를 사용한다. 원리는 '앞에서부터 논리값을 확인하며 논리식의 값이 확정되는 순간 남은 명령어는 무시한다'. 라고 할 수 있다.
>> 명령어1 && 명령어2 : 명령어1의 실행이 실패했을 경우 식의 값이 거짓임이 확정되므로 명령어2는 실행하지 않는다. >> 명령어1 || 명령어2 : 1의 실행이 성공했을 경우 바로 식의 값이 참이 되므로 2를 실행하지 않는다.
파일명 대치, 명령어 대치
파일명 대치 : 문자열 조건을 설정하는 '와일드카드'를 사용해 조건에 맞는 파일명을 모두 선택할 수 있는 기능이다. 와일드카드에는 3가지가 있다.
>> * : 아무 문자열이나 다 된다. 공백도 가능하다.
>> ? : 딱 하나의 문자만 가능하다. 공백도 안 되고 두 글자 이상도 안 된다.
>> [..] : 대괄호 내에 나열된 문자만 가능하다. [a,b,c]도 가능하고 ~를 사용해 [a~c]로 나타낼 수도 있다.
사용법은 다음과 같다. 예를 들어 확장자가 pdf인 모든 파일을 나타내고자 하면 '뭐가 됐든 .pdf로 끝나는 파일명'을 의미하는 *.pdf과 같이 나타낼 수 있다. 이런 식으로 파일명 대치를 수행하면, 대치할 문자열 *.pdf의 위치에 이름이 .pdf로 끝나는 모든 파일의 실제 이름이 하나씩 대입된다.
그 중에서 파일명(확장자 제외)이 2글자인 파일들은 정확히 두 개의 문자를 나타내는 ??.pdf로 표현할 수 있다. 그 두 글자가 알파벳 대문자여야 한다면 [A~Z][A~Z].pdf로 나타내면 된다. 와일드카드는 종류가 3가지밖에 없지만 이를 이용해 정말 다양한 조건을 나타낼 수 있어, 반드시 사용에 익숙해져야 한다.
명령어 대치 : 명령어를 ``로 감싸면 해당 명령어의 출력 결과를 하나의 값으로 사용할 수 있다. 위에 '파이프' 설명 예시로 who | wc - l을 언급했는데, 이 명령어를 ``로 감싸 안내 메세지 출력에 사용할 수 있다.
echo 현재 접속자 수 : `who | wc -l`
따옴표 : 문자열을 감싸 문자열 내에서 원하지 않는 대치의 발생을 방지한다. 가장 바깥에 있는 따옴표의 효과만 적용되며 큰따옴표 " "는 대표문자 대치만, 작은따옴표 ' '는 모든 대치를 방지한다.