728x90

import java.util.Arrays;
import java.util.Collections;
import java.util.stream.Stream;

public class StringtoInt {
public static void main(String[] args) {

/*
 * 문자열 s에 나타나는 문자를 큰것부터 작은 순으로 정렬해 새로운 문자열을 리턴하는 함수, solution을 완성해주세요. s는 영문
 * 대소문자로만 구성되어 있으며, 대문자는 소문자보다 작은 것으로 간주합니다.
 * 
 * 제한 사항 str은 길이 1 이상인 문자열입니다.
 */

String s = "Zbcdefg";

//String 변수안에 담긴 문자열들을 .split()을 통해 한글자씩 배열로 분리
String[] str = s.split("");


//오름차순 정렬 Arrays.sort(str);
Collections.reverse(Arrays.asList(str));

//join 메서드를통해 배열안의 요소를 스트링으로 합치기 String.join("", str);
String b = String.join("", str);

System.out.println(b);
    }
}

728x90

'알고리즘' 카테고리의 다른 글

[프로그래머스] 두 개 뽑아서 더하기  (0) 2022.02.11
[프로그래머스] 체육복  (0) 2022.02.08
728x90

tomcat이 crontab상으로 돌고있는 respawn.sh 을 통해 살아는있었지만

ps-ef상으로는 같은톰캣이 중복으로 떠있는 이상한 이슈가 생겼다.

해당 톰캣로그를 조회해보니  reuest시마다 connection refused:111 오류를 뱉어내는

문제가 발생하고있었다.

shutdown.sh을 통해 tomcat 구동 종료를 시도해보았지만 종료되지않고

계속 tomcat은 같은 pid로 구동되고있었다 was 관련 설정문제로 예측하였지만 원인파악을 할수없었고

구글링에서 netstat -anp | grep {tomcat port} 명령어를 통해 문제가 발생한 톰캣포트를 조회해본결과

정상 port는 TIMEWAIT 상태였고 문제가 발생한 port는  CLOSE WAIT 상태였다

자바라이브러리 poco오류가 계속발생한뒤 오류응답을뱉어냈는데 was문제가아닌

자바라이브러리상 문제가있어 네트워크연결이된채로 쓰레드를물고있을경우 shutdown.sh 을통해서도

톰캣구동이 종료되지않으며 kill -9 명령어를 통해서만 프로세스를 죽인후 재기동해야했다.

netstat -tnlp명령어를통해 현재 떠있는  PID를 확인할수있다.



728x90

'Linux' 카테고리의 다른 글

[Nginx] 엔진엑스 기본 환경 설정  (0) 2022.03.24
[쉘 스크립트] 반복문 예제  (0) 2022.02.24
[쉘스크립트]$((...))  (0) 2022.02.24
[쉘 스크립트] 위치 매개변수  (0) 2022.02.23
[쉘스크립트] 변수 치환  (0) 2022.02.23
728x90

https://developpaper.com/centos7-installs-nginx-integration-lua/

 

Centos7 Installs Nginx Integration Lua - Develop Paper

Preface My computer is Mac and my operating system is MacOS Mojave. The computer is equipped with a virtual machine. Centos7 operating system is installed on the virtual machine and Nginx and Luau class libraries are installed on it. The whole process is r

developpaper.com

Nginx Lua Moudle 설치

 

 

 

default_type 'text/plain'; : 데이터 타입 설정

 

content_by_lua_block {

      lua 관련된 내용 삽입가능한듯?

}

 

ngx.req.read_body()  // requestbody 데이터를 읽어드린다.

local_data = ngx.req.get_body_data() //읽어들인 데이터를 data변수안에 저장

 

 

ㄴ 다른 uri 호출 결과 status와 body를 호출하는 코드

 

ngx.location.capture("/some_other_location")

728x90

'lua script' 카테고리의 다른 글

Nginx lua Module  (0) 2022.03.23
728x90

https://12bme.tistory.com/366

728x90
728x90

https://github.com/openresty/lua-nginx-module#status

 

nil(Null) 체크

 

Lua nil은 값이 없다는것을 의미한다.

if keys ~= nil then 
     ngx.log(ngx.INFO, "nil이 아니다.")
end

if keys == nil then
     ngx.log(ngx.INFO, "nil이다")
end

타입변환

tonumber("10") -- 10
tostring(10) -- "10"

타입 구하기

 

공유 메모리의 키를 가져오는데, 어떤 형태인지 알아볼때 사용한다.

ngx.log(ngx.INFO), type(ngx.shared.shared_dict:get_keys()))

For Loop

공유 메모리의 키를 모두 가져와서 For Loop를 돌릴 수 있다.

-- k : 인덱스, v : 키 문자열

for k , v in pairs(ngx.shared.shared_dict:get_keys()) do
     ngx.log(ngx.INFO, v) -- 각 키 값들이 출력됨.
end

문자열

string.len("abcdefg") -- 7

-- sprintf처럼 포맷 지정
string.format(%s/AAA', 'BBB') -- BBB/AAA

-- 문자열 찾기
local str = "This is a string."
if string.matchh(str, "This") then
   -- 찾음
end

-- 문자열 치환
string.gsub(ngx.var.request_url, "?.*", "") -- >?부터 제거

날짜 / 시간

lua 공식 사이트 연결

시간 포맷

os.time() -- 1490167184
os.date("%c", os.time()) -- Wed Mar 22 16:20:06 2017 (KST 또는 시스템 설정에 따름)
os.date("!%c", os.time()) -- Wed Mar 22 07:20:47 2017 (UTC)

Table

-- 카운팅
table.getn(ngx.shared.shared_dict)

Logging

ngx.log(ngx.INFO, "Log")
ngx.log(ngx.DEBUG, "Log")
ngx.log(ngx.WARN, "Log")
ngx.log(ngx.ERR, "Log")

모듈화

모듈화를 위해서 다음과 같은 형태로 파일을 만들어서 사용할 수 있다.

-- mymodule.lua
local _M = {}
 
function _M.main(ctx)
    ctx.foo = "bar"
end
 
return _M

이렇게 작성한 모듈은 다음과 같이 사용할 수 있다.

 
1
2
3
local Mymodule = require 'mymodule';
 
Mymodule.main({foo: "foo"})

스크립트 경로 가져오기

script_path()를 호출하는 파일의 경로를 구할 수 있다. 해당 파일을 기준으로 다른 파일 경로를 가져올 때 유용하다.

 
1
2
3
4
5
6
function script_path()
    local str = debug.getinfo(2, "S").source:sub(2)
    return str:match("(.*/)")
end
 
script_path() -- /home/luascript/access.lua

동적으로 모듈 호출

 
1
2
3
4
5
local pcall = pcall
local ok, upstream = pcall(require, "ngx.upstream")
if not ok then
     error("ngx_upstream_lua module required")
end

 

Nginx Lua Module 전용

ngx_http_lua_module

Nginx에 Lua 코드를 끼워넣어 사용할 수 있는 모듈로 기본적으로 nginx에서 제공되지 않고, 직접 설치해야 한다.

공식사이트

출력

원하는 단계에 넣으면 중간에 다른 결과를 출력할 수 있다.

 
1
2
3
ngx.header.content_type = 'text/html';
ngx.print("hello")
ngx.exit(200)

 

버전 정보

 
1
2
ngx.config.nginx_version -- nginx 버전
ngx.config.ngx_lua_version -- nginx lua 버전 9015

http 요청

ngx.location.capture는 nginx 워커에서 특정 uri에 추가 요청을 할 수 있다.

 
1
2
3
4
5
6
7
local res = ngx.location.capture("/auth")
 
if res then
    ngx.say("status: ", res.status)
    ngx.say("body:")
    ngx.print(res.body)
end

 

redirect

특정 페이지로 리다이렉트할 수 있다.

 
1
2
3
4
5
-- redirect
ngx.redirect("http://"..ngx.req.get_headers()["Host"].."/page")
 
-- exec
ngx.exec("@bar", "a=goodbye");

exec는 redirect와 다르게, 내부 리다이렉트를 하고, 새로운 외부 HTTP트래픽과 관련이 없다.

Header 관련

 
1
2
3
4
5
6
7
-- upstream으로 전달
ngx.req.set_header("X-Epoch", ngx.time())
 
-- 응답 헤더에 추가한다. phase 값을 공유할 수도 있다. : access phse -> header_filter phase
ngx.header['X-Epoch'] = ngx.time()
ngx.header['Content-Type'] = "text/html"
ngx.header['Set-Cookie'] = 'Foo=abc; path=/'

nginx에서 설정한 변수 사용하기

nginx.conf:

 
1
2
3
4
5
6
map "${http_host}${request_uri}" $value_in_lua {
    default "default_value";
 
    # 정규식 사용 가능. ~ : case-sensitive, ~* : case-insensitive
  ~*^(.+\.)?hostname/path "value";
}

 

주소가 설정한 값과 일치하면 그 값을 lua에서 다음과 같이 사용할 수 있다.

 
1
ngx.var.value_in_lua -- value

 

3rd party module

LIP – ini Parser

LIP는 Lua INI Parser다. ini 파일을 불러오고, 저장할 수 있다.

 
1
2
3
-- ini 불러오기
local LIP = require 'LIP';
local config = LIP.load('/home/luascript/config.ini');

 

CJSON

CJSON은 LUA에서 JSON을 지원하는 모듈이다.

설치하기

다음 페이지 다른 JSON 모듈을 비교한다.

JSON 모듈 비교

에러

a temporary file while reading upstream

lua에서 다음 에러가 발생한다.

 
1
a temporary file /path/file while reading upstream, client: 000.000.000.000, server: localhost, request: "GET /file.php HTTP/1.1", upstream: "http://127.0.0.1:10000/file.php", host: "domain"

문제 생기는 부분을 확인하니 다음과 같이 이미지를 base64로 출력하는 부분의 사이즈가 설정한 값보다 커서 생긴 문제였다. 이미지 사이즈에 맞게 프록시 버퍼의 크기를 늘려줬다.

 
1
2
<?php
<img src='data:image/jpeg;base64, <?php echo $image?>' width="100%">

nginx 설정을 변경했다.

 
1
proxy_buffers 500 8k;

 

예제 프로그램이라서 base64로 이미지를 출력했지만, 버퍼를 늘리는 것보다 이미지는 static 서버를 통해 제공하는 것이 좋다.

 

https://blog.kichul.co.kr/2017/03/13/2017-03-13-lua-note/

 

728x90

'lua script' 카테고리의 다른 글

Nginx lua Moudule install / Code testing  (0) 2022.03.25
728x90

명령어 목록

 

ls 

 

파일 "목록"을 보여주는 기본 명령어로서, 너무 간단해서 과소평가되기 쉬운 명령어지만 그렇지 않습니다.

예를 들면, 하위 디렉토리까지 표시해주는 -R 옵션을 쓰면 디렉토리 구조를 트리같은 형태로 보여줍니다.

 

흥미로운 다른 옵션들로는, 파일 크기대로 정렬해주는 -S, 변경 시간으로 정렬해주는 -t, 파일의 inode를 보여주는 -i 가 --R 하위디렉토리도 표시 -F 파일타입표시까지 있습니다(예 12-3 참고).

cat (concatenate (연속으로 있다)) 파일을 표준 출력으로 뿌려 줍니다.

보통 재지향(>이나 >>)과 같이 써 여러 파일을 한 파일로 만들어 줍니다.

cat에 -n 옵션을 주면 대상 파일의 모든 줄 앞에 줄번호를 붙여줍니다.

        -b 옵션은 빈 줄이 아닌 줄에만 줄번호를 붙여 줍니다.

        -v 옵션은 출력할 수 없는 문자들을 ^ 표기법으로 보여줍니다.

 

tac는 cat을 거꾸로 쓴 것인데, 파일 끝에서부터 거꾸로 보여줍니다.

 

 

rev

파일의 각 줄을 거꾸로 뒤집어 표준출력을 내보냅니다. tac과 다른 점은 줄의 순서는 그대로 살리고

각 줄을 줄 끝에서 줄 처음으로 뒤집는다는 것입니다.

 

cp

파일 복사(copy) 명령어입니다. cp file1 file2 file1을 file2로 복사하는데 file2가 이미 존재한다면 덮어 씁니다(예 12-5 참고).

 

작은 정보: 특별히 유용한 옵션은 아카이브 옵션, -a(디렉토리 트리 전체를 복사할 때)와 재귀 옵션인 -r과 -R입니다

 

mv

 

파일 이동(move) 명령어입니다. cp와 rm을 합친 것과 동일합니다. 여러개의 파일을 한 디렉토리로 옮기거나 디렉토리 이름을 바꿀 때 쓰일 수도 있습니다.

 

rm

 

파일을 삭제(remove), -f 옵션은 읽기 전용 파일도 강제로 지워줍니다.

ㄴ [재귀옵션인 -r과 같이 쓰이면 디렉토리 트리 이하 모든 파일을 지워버립니다.]

 

rmdir

 

디렉토리를 삭제. 삭제할 디렉토리안에는 안 보이는 "도트 파일"을 포함해서 아무 파일도 없어야 이 명령어가 제대로 실행합니다.

 

mkdir

 

디렉토리 만들기, 새로운 디렉토리를 생성해 줍니다. mkdir -p project/programs/December 라고 하면 주어진 디렉토리를 만들어 주는데 -p 옵션을 주면 자동으로 필요한 부모 디렉토리가 만들어 집니다.

 

chmod

 

파일의 속성을 변경

chattr

파일 속성을 바꿔줍니다. 위에서 설명한 chmod와 똑같은 역할을 하지만 문법이 약간 다르고 오직 ext2 파일 시스템에 대해서만 동작합니다.

 

ln

이미 존재하는 파일에 대한 링크를 만들어 줍니다. 심볼릭이나 "소프트" 링크 플래그를 나타내는 -s 옵션을 많이 씁니다. 참조되는 원래의 파일이 하나 이상의 이름을 갖도록 해 주기 때문에 별칭보다는 더 좋은 방법입니다(예 5-6 참고).

ln -s oldfile newfile 라고 하면 이미 존재하는 oldfile에 대한 새로운 링크 파일인 newfile을 만들어 줍니다.

 

find
-exec COMMAND \;

find가 찾아낸 각각의 파일에 대해 COMMAND를 실행합니다. COMMAND는 \;로 끝나야합니다.(find로 넘어가는 명령어의 끝을 나타내는 ;를 쉘이 해석하지 않도록 이스케이프 시켜야 합니다.) COMMAND에 {}이 포함되어 있으면 선택된 파일을 완전한 경로명으로 바꿔줍니다.




예 12-2. Badname, 파일 이름에 일반적이지 않은 문자나 공백 문자를 포함하는 파일을 지우기.

예 12-3. inode 로 파일을 지우기

파일명을 통해 inode 추출하는 명령어

ls -i | grep "file.sh" | awk '{print $1}'

 

xargs

명령어에 인자들을 필터링해서 넘겨 주고 그 명령어를 다시 조합하는 데 쓸 수도 있습니다. xargs는 입력을 필터용으로 작게 조각내서 명령어가 처리하게 해 줍니다. 역따옴표의 강력한 대용품이라고 생각하면 됩니다. 역따옴표를 써서 too many arguments란 에러가 났을 때, xargs로 바꿔 쓰면 성공할 수도 있습니다. 보통은 표준 입력이나 파이프에서 데이터를 읽어 들이지만 파일의 출력에서도 읽을 수 있습니다.

 

xargs의 기본명령어는 echo 입니다.

 

ls | xargs -p -l gzip 은 현재 디렉토리의 모든 파일에 대해 한번에 한 파일씩 물어보면서 gzip으로 묶어줍니다.

ls | xargs -n 8 echo 는 현재 디렉토리의 파일들을 한 줄에 8 개씩 끊어서 보여줍니다.

 

find -print0나 grep -lZ와 함께 쓰는 -0이 있습니다.

 

find / -type f -print0 | xargs -0 grep

 

작은 정보: 다른 유용한 옵션으로 find -print0 grep -lZ와 함께 쓰는 -0이 있습니다. 이 옵션은 공백 문자나 따옴표가 들어간 인자를 처리할 수 있게 해줍니다.

find / -type f -print0 | xargs -0 grep -liwZ GUI | xargs -0 rm -f

grep -rliwZ GUI / | xargs -0 rm -f

 

예 12-4. 시스템 로그 모니터링용 xargs 로그 파일

위의 두 가지 모두 "GUI"를 포함하고 있는 어떤 파일도 지워 줍니다. (Thanks, S.C.)

예 12-5. copydir. xargs로 현재 디렉토리를 다른 곳으로 복사하기

 

expr

다목적 표현식 평가 명령어 : 주어진 연산에 따라 자동으로 계산하거나 평가합니다. 이 때, 인자는 빈칸으로 분리되어야 합니다.

 

산술, 비교, 문자열, 논리 연산등이 가능합니다.

 

expr 3 + 5

8리턴

 

expr 5 % 3

2리턴

 

y=`expr $y + 1`

변수를 증가. let y=y+1 이나 y=$(($y+1)) 과 같음

 

z=`expr substr $string $position $length`

$string의 $position에서부터 $length만큼의 문자열조각(substring)을 추출해 냄.

 

중요: match 대신 : 연산자를 쓸 수 있습니다. 예를 들면, 위의 예제에서 b=`expr $a : [0-9]*`  b=`expr match $a [0-9]*` 과 완전히 동일합니다.

 

시간/날짜 명령어

 

date

간단하게 date라고만 치면 날짜와 시간을 표준 출력으로 보여줍니다. 이 명령어에서 진짜 재밌는 부분은 형식화와 파싱 옵션입니다.

zdump

주어진 타임 존에 해당하는 시간을 에코.

time

명령어 실행 시간에 대한 아주 자세한 통계들을 보여줍니다.

time ls -l / 의 출력은 다음과 같습니다.

touch

파일에 대한 접근/수정 시각을 현재 시각이나 특정한 시각으로 바꿔 주는 유틸리티지만 새 파일을 만들 때 쓸 수도 있습니다. zzz란 파일이 없다고 가정하고 touch zzz 라고 하면 크기가 0인 zzz을 새로 만들어 줍니다. 이런 식으로 시간 정보를 갖는 빈 파일을 만들어서 프로젝트의 변경 날짜를 추적하는데 쓰는 등의 사용법이 가능합니다.

touch 명령어는 : >> newfile 과 동일한 동작을 합니다(보통 파일에 대해서).

 

at

작업 제어 명령어인 at은 주어진 명령어들을 특정 시간에 수행합니다. 이 명령어는 표면상으로는 crond과 닮아 있지만 여러 명령어들을 단지 한 번만 수행하려고 할 때 주로 쓰입니다.

at 2pm January 15 라고 하면 그 시간에 실행시킬 명령어들을 물어보는데 이 명령어는 실용적인 목적때문에 쉘 스크립트와 호환되는 명령어면 다 됩니다. 스크립트에서 한 줄에 이것을 타이핑할 것이기 때문입니다. 입력은 Ctl-D 로 끝냅니다.

-f 옵션을 쓰거나 입력 재지향(<)을 써서 파일에 저장되어 있는 명령어들을 읽어 들일 수 있습니다. 이 파일은 쉘 스크립트가 될 수도 있지만 당연히 사용자 입력이 필요 없어야 합니다. 실행할 파일에 run-parts 명령어를 넣어 두면 다른 종류의 여러 스크립트들을 돌릴 수 있기 때문에 아주 멋지게 쓸 수 있습니다.

batch

batch at과 비슷한 작업 제어 명령어지만 다른 점은 시스템 부하가 0.8 이하인 경우에만 명령어들을 실행합니다. at처럼 -f 옵션을 써서 실행할 명령어를 파일에서 읽을 수 있습니다.

cal

깔끔한 형태의 월별 달력을 표준출력으로 출력합니다. 현재를 비롯해 아주 먼 과거나 미래도 보여 줍니다.

sleep

쉘의 wait 루프와 같습니다. 주어진 초단위 시간 동안 아무일도 안 하면서 멈추어 있습니다. 타이밍, 혹은 백그라운드로 돌면서 특정한 사건이 일어나는지 주기적으로 확인하는등의 경우에 유용하게 쓰일 수 있습니다(예 30-5 참고).

usleep

마이크로슬립(Microsleep)("u"는 그리스 문자 "mu"로 읽던가 마이크로(micro) 접두사 그대로 읽으면 됩니다). 이 명령어는 위에서 설명한 sleep과 하는 일이 같지만 마이크로초 동안 "잠들어" 있습니다. 아주 짧은 시간 동안의 타이밍에 쓰이거나 굉장히 잦은 간격으로 진행되는 프로세스를 폴링할 때 쓰일 수 있습니다.

hwclock, clock

hwclock는 시스템의 하드웨어 클럭을 읽거나 조절해 줍니다. 몇몇 옵션은 루트 권한이 필요합니다. /etc/rc.d/rc.sysinit 시스템 구동 파일은 부팅시에 hwclock을 써서 하드웨어 클럭으로 시스템 시간을 맞춰줍니다.

clock 명령어는 hwclock과 동의어입니다.

 

sort

주로 파이프에서 필터로 쓰여 파일을 정렬할 때 쓰입니다. 다양한 키나 문자 위치에 따라 텍스트 스트림이나 파일 전체를 정렬할 수 있습니다. -m 옵션을 쓰면 이미 정렬된 파일을 합쳐줍니다. info page에서 많은 기능과 옵션들을 볼 수 있습니다. 예 10-8 예 10-9를 참고하세요.

 

tsort

위상 정렬(Topological sort) 명령어로서, 공백문자로 구분되는 문자열의 쌍을 읽어 패턴에 따라 정렬.

 

diff, patch

diff: 유연한 파일 비교 유틸리티. 대상 파일들을 줄 단위로 차례 차례 비교해 줍니다. 예를 들어 낱말 사전을 비교하는 어플리케이션에서 sort uniq를 써서 파일을 필터링하고 파이프를 통해 diff로 넘겨주는 상황등에서 유용하게 쓰일 수 있습니다. diff file-1 file-2 는 두 파일에서 서로 다른 줄이 있으면 그 줄이 속해 있는 파일을 캐럿과 함께 보여줍니다.

--side-by-side 옵션을 주면 비교할 파일을 서로 구분된 컬럼에 두고 줄 단위로 비교하면서 일치하지 않는 줄을 표시해 줍니다.

diff의 다양한 프론트엔드(frontend)로는 spiff, wdiff, xdiff, mgdiff가 있습니다.

작은 정보: diff 는 비교할 두 파일이 똑같으면 종료 상태 0을 리턴하고 다르면 1을 리턴합니다. 이것 때문에 diff를 쉘 스크립트의 테스트문에서 쓸 수 있습니다(아래 참조).

diff는 보통 patch에 쓸 다른 파일을 만들어 내는데 쓰입니다. -e 옵션은 diff가 자신의 출력을 ed ex 스크립트에서 쓸 수 있는 파일로 만들어 내게 합니다.

 

patch: 유연한 버전 관리 유틸리티. patch diff가 만들어낸 다른 파일이 주어지면 패키지의 이전 버전을 새로운 버전으로 업그레이드 해 줄 수 있습니다. 이렇게 하면 새롭게 발표된 패키지 전체를 배포할 필요 없이 비교적 작은 "diff" 파일만 배포하면 되므로 아주 편리합니다. 따라서 커널 "패치"는 리눅스 커널의 빈번한 배포시 더 선호됩니다.

cmp

cmp 명령어는 위에서 설명한 diff의 간단한 버전입니다. diff가 두 파일간의 차이점에 대해서 보고해 주는 반면, cmp는 단지 두 파일간에 서로 다른 부분만을 보여줍니다.

참고: cmp diff처럼 두 파일이 똑같다면 종료 상태 0을 리턴하고 다르다면 1을 리턴합니다. 따라서 쉘 스크립트의 테스트문에서 cmp를 쓸 수 있습니다.

예 12-8. 스크립트에서 두 파일을 비교하기 위해 cmp 쓰기.

 

작은 정보: gzip으로 묶인 파일에는 zcmp를 쓰세요.

comm

다목적 파일 비교 유틸리티. 제대로 된 결과를 얻으려면 파일 내용이 정렬돼 있어야 합니다.

comm -options first-file second-file

comm file-1 file-2 출력은 세 칸으로 이루어 집니다:

  • column 1 = file-1에 유일한 줄
  • column 2 = file-2에 유일한 줄
  • column 3 = 두 파일 양쪽에 공통으로 나타나는 줄

다음 옵션은 하나 이상의 출력 칸을 제거해 줍니다.

  • -1  1번 칸을 제거
  • -2  2번 칸을 제거
  • -3  3번 칸을 제거
  • -12  1번과 2번 칸을 제거, 등등.

uniq

이 필터는 정렬된 파일에서 중복된 줄을 제거합니다. 보통 파이프에서 sort와 같이 쓰입니다.

유용한 옵션인 -c을 쓰면 입력 파일의 각 줄 앞에 중복된 수를 표시해 줍니다.

sort INPUTFILE | uniq -c | sort -nr 이라고 하면 INPUTFILE 파일의 발생 빈도 목록을 만들어 줍니다(sort 명령어의 -nr은 숫자를 거꾸로 정렬). 이 템플릿은 로그 파일이나 사전 목록, 구문 분석이 필요한 어떤 것에도 쓰일 수 있습니다.

예 12-9. 낱말 빈도수 분석

cut으로 마운트 된 파일 시스템 목록 알아내기: 쓰기:

cut으로 OS와 커널 버전 알아내기:

cut 으로 이 메일 폴더에서 메세지 헤더를 뽑아내기

colrm

칸 제거 필터. 파일에서 여러 칸(글자들 단위)을 지워주는데, 칸 범위를 지정하지 않으면 원래 파일을 표준출력으로 다시 내보냅니다. colrm 2 4 <filename 이라고 하면 텍스트 파일인 filename 각 줄의 두 번째 칸에서 4 번째 칸의 글자를 지웁니다.

주의

파일에 탭이나 출력 할 수 없는 글자가 포함되어 있다면 예상치 못한 동작을 할 수도 있습니다. 이런 경우에는 colrm 앞에 expand unexpand를 파이프로 걸어서 써 보기 바랍니다.

paste

서로 다른 파일들을 여러 단으로 나뉘어진 하나의 파일로 만들어 주는 툴로서, cut과 같이 써서 시스템 로그 파일을 만드는데 유용합니다.

join

특수한 목적을 가진 paste류의 명령어라고 보면 됩니다. 두 파일을 의미있는 형태로 묶어서 본질적으로는 간단한 관계 데이터베이스를 만들어 주는 강력한 유틸리티입니다.

join 명령어는 정확히 두 파일에 대해서 동작하지만 두 파일 사이에 공통으로 표시된 필드(tagged field)(보통은 숫자 라벨)가 들어 있는 줄에 대해서만 합쳐서 결과를 표준출력에 씁니다. 제대로 동작하려면 두 파일 모두, 표시 필드가 제대로 정렬되어 있어야 합니다.

 

참고: 표시 필드는 결과에서 한 번만 나옵니다.

head

파일 앞부분을 표준출력으로 보여 줍니다(기본적으로 10줄을 보여주지만 따로 지정해 줄 수도 있습니다). head는 재밌는 옵션이 몇 개 있습니다.

 

tail

파일의 마지막 부분을 표준출력으로 보여 줍니다(기본적으로10줄). 보통, 시스템 로그 파일의 변경 사항을 추적할 때 쓰는데, 파일 뒷부분에 계속 덧붙여지는 사항을 볼 수 있게 해 주는 -f 옵션을 주면 됩니다..

 

예 12-11. tail로 시스템 로그를 모니터하기

 

grep

정규 표현식을 쓰는 다목적 파일 검색 도구로서, 원래 예전의 라인 에디터인 ed의 명령어나 필터였던 g/re/p에서 따온 것으로 global - regular expresstion - print란 뜻입니다.

 

grep pattern [file...]

 

대상 파일에서 보통 텍스트이거나 정규 표현식인 pattern을 찾아 줍니다.

대상 파일이 주어지지 않는다면 파이프에서 쓰여서 다른 명령어의 표준출력에 대한 필터로 동작합니다.

-i 옵션은 대소문자 구분없이 찾도록 해줍니다.

-l 옵션을 일치하는 줄이 아니라 일치하는 줄이 아니라 일치하는 줄이 들어 있는 파일만 보여줍니다.

-n 옵션은 일치하는 줄과 그 줄번호를 같이 보여줍니다.

-v (혹은 --invert-match) 옵션은 일치하는 패턴을 걸러내 줍니다.

-c (--count) 옵션은 일치하는 패턴을 보여주지 않고 일치한 횟수만 보여줍니다.

대상 파일을 하나 이상 적어주면 일치하는 파일도 같이 보여 줍니다.

작은 정보: 오직 하나의 파일에서만 찾으려고 할 때 grep이 강제로 파일이름을 보여주게 하고 싶으면 두 번째 파일로 /dev/null을 주면 됩니다.

grep은 일치하는 패턴을 찾으면 종료 상태 0을 리턴하는데 출력을 안 하게 해 주는 -q 옵션과 같이 스크립트의 테스트 문에서 쓰면 유용하게 쓸 수 있습니다.

예 30-5 은 시스템 로그 파일에서 grep으로 특정 낱말 패턴을 찾는 것을 보여줍니다.

예 12-12. 스크립트에서 "grep"을 에뮬레이트 하기

참고: egrep  grep -E와 같습니다. 좀 더 유연한 검색 능력을 갖는 확장 정규 표현식 셋을 사용합니다.

fgrep  grep -F와 같습니다. 문자 그대로의 검색(정규 표현식 안 씀)만 하기 때문에 속도가 약간 빠릅니다.

agrep  grep이 유사(approximate) 매칭을 할 수 있게 확장해 줍니다. 찾을 문자열과 찾은 문자열은 주어진 숫자 만큼의 문자가 다를 수도 있습니다. 이 유틸리티는 리눅스 배포판에서 기본으로 포함되지 않습니다.

작은 정보: 압축된 파일에서 검색을 하려면 zgrep, zegrep, zfgrep을 쓰세요. 압축 안 된 파일에 대해서도 동작하지만 grep, egrep, fgrep 보다는 약간 느립니다. 압축 파일과 비압축 파일이 섞여 있을 때 사용하면 편리합니다.

bzip으로 압축된 파일에서 검색을 하려면 bzgrep 을 쓰세요.


look

look grep과 비슷하게 동작하지만 정렬된 낱말 목록인 "사전"에 들어 있는 낱말에 대해서만 찾습니다. 따로 지정하지 않으면 /usr/dict/words 에 들어 있는 낱말만 찾는데 다른 사전 파일을 지정해 줄 수도 있습니다.

예 12-13. 목록에 들어 있는 낱말들의 유효성 확인하기

sed, awk

텍스트 파일이나 명령어 출력을 파싱하는데 특히 알맞은 스크립트 언어입니다. 홀로 쓰일 수도 있고 파이프 중간이나 쉘 스크립트에서 쓰일 수도 있습니다.

sed

많은 ex 명령어들을 배치 모드에서 쓸 수 있게 해주는 비대화형(non-interactive) "스트림 에디터"입니다. 쉘 스크립트에서 아주 자주 쓰입니다.

awk

프로그램 가능한 파일 분석및 형식화 명령어로서, 구조화된 텍스트 파일의 필드나 컬럼을 뽑아내고 조작하는데 아주 적당하며, 문법은 C와 비슷합니다.

wc

wc는 파일이나 I/O 스트림에 나타나는 "낱말 갯수"(word count)를 알려줍니다:

wc -w 는 낱말 갯수만 알려줍니다.

wc -l 은 줄 수만 알려줍니다.

wc -c 는 글자 수만 알려줍니다.

wc -L 을 가장 긴 줄의 길이만 알려줍니다.

 

wc 로 현재 디렉토리에 .txt 파일이 몇 개 있는지 알아내기:

wc 로 d 에서 h 사이의 문자로 시작되는 파일들 크기의 전체 합을 구하기.

wc 로 이 책의 메인 소스 파일에서 "Linux"가 몇 번이나 나오는지 알아보기..

예 12-27  예 16-5 도 참고.

몇몇 명령어는 자신의 옵션으로 wc의 일부 기능을 갖고 있기도 합니다.

tr

문자 변환 필터.

경고
적절하게 쿼우팅이나 대괄호로 묶어줘야 합니다. 쿼우팅은 tr 명령어에서 쓰이는 특수한 문자들이 쉘에 의해 재해석 되지 않도록 막아줍니다. 대괄호는 쉘이 확장을 못 하도록 쿼우트 되어야 합니다.

tr "A-Z" "*" <filename 이나 tr A-Z \* <filename  filename에 들어 있는 모든 대문자를 별표로 변환해서 표준출력으로 내 보냅니다. 몇몇 시스템에서는 이렇게 하면 안 되고 tr A-Z '[**]' 이라고 해야 제대로 동작할 수도 있습니다.

-d 옵션은 지정된 범위에 해당하는 문자들을 지워 줍니다.

--squeeze-repeats(나 -s) 옵션은 연속적인 문자들 중에서 첫번째만 남기고 나머지 문자들은 지워 줍니다. 이 옵션은 과도한 공백 문자를 지울 때 유용합니다.

예 12-14. toupper: 파일 내용을 모두 대문자로 바꿈.

예 12-16. du: 도스용 텍스트 파일을 UNIX용으로 변환.

예 12-17. rot13: 초허접(ultra-weak) 암호화, rot13.

tr 변종들
tr 유틸리티는 역사적으로 두 개의 변종을 갖고 있습니다. BSD 버전은 대괄호를 쓰지 않지만(tr a-z A-Z), SysV 버전은 씁니다(tr '[a-z]' '[A-Z]'). GNU 버전은 BSD 버전을 닮았기 때문에 대괄호속의 문자 범위를 꼭 쿼우팅 해 줘야 합니다.

fold

입력 줄을 주어진 넓이로 접어주는(wrap) 필터. 특별히 유용한 -s 옵션을 쓰면 낱말 사이의 빈 칸에서 줄을 나눠줍니다(예 12-19 예 A-2 참고).

fmt

간단한 파일 형식화 명령어로 파이프 중간에 필터로 쓰여 긴 줄을 "접기"(wrap) 위해 쓰입니다.

예 12-19. 파일 목록 형식화.

예 12-4 참고.

작은 정보: fmt의 강력한 대체품인 Kamil Toman의 par 유틸리티는 http://www.cs.berkeley.edu/ ~amc/Par/ 에서 구할 수 있습니다.

ptx

ptx [targetfile] 명령어는 targetfile의 permuted index(상호 참조 리스트 - cross-reference list)를 출력해 줍니다. 필요하다면 여기서 나온 결과를 나중에 필터링이나 형식화해서 쓸 수도 있습니다.

column

컬럼 형식화 명령어. 목록 형태의 텍스트 출력의 적당한 곳에 탭을 넣어서 "예쁜 출력" 테이블을 얻게 해 주는 필터입니다.

예 12-20. column 으로 디렉토리 목록을 형식화 하기

nl

줄 번호 매기기 필터. nl filename 이라고 하면 filename의 빈 칸을 제외한 각 줄에 연속적인 번호를 붙여서 표준출력으로 보여 줍니다. filename을 지정해 주지 않으면 표준입력에 대해서 동작합니다.

예 12-21. nl: 자기 자신에게 번호를 붙이는 스크립트.

pr

출력 형식화 필터. 파일이나 표준출력을 프린터로 찍거나 출판용이나 스크린으로 보기 좋은 섹션 형태로 페이지를 매겨 줍니다. 행과 열을 조작하기, 여러 줄을 합치기, 마진을 넣어 주기, 줄에 번호를 매겨 주기, 페이지 헤더를 붙여 주기, 여러 파일을 합치기등을 비롯한 다양한 옵션이 가능합니다. pr nl, paste, fold, column, expand의 기능을 합친 것보다 더한 능력을 가진 명령어입니다.

pr -o 5 --width=65 fileZZZ | more 라고 하면 fileZZZ를 마진을 5로 하고 전체 폭을 65로 하고 멋있게 페이지를 매겨서 스크린에 뿌려 줍니다.

특별히 유용한 옵션인 -d는 한 줄마다 강제로 빈 줄을 넣어줍니다(double-spacing, sed -G와 같습니다).

gettext

프로그램의 출력을 다른 언어로 번역해서 보여주는 GNU 지역화(localization) 유틸리티입니다. 처음엔 C 프로그램을 위해서 쓰였지만 쉘 스크립트에서도 쓰입니다. info page를 참고하기 바랍니다.

iconv

주로 지역화에서 쓰이는 명령어로 파일을 다른 인코딩(문자셋)으로 변환해 줍니다.

recode

이 명령어는 iconv의 개선판이라고 보면 됩니다. 파일을 다른 인코딩으로 변환해주는 이 다목적 유틸리티는 표준 리눅스 설치시에는 포함되지 않습니다.

groff, gs, TeX

Groff, TeX, 포스트스크립트(postscript)는 출판용 원고나 형식화된 비디오 디스플레이용 텍스트 마크업 언어(text markup language)들입니다.

맨 페이지 groff을 씁니다(예 A-1 참고). 고스트스크립트(ghostscript, gs)는 포스트스크립트 해석기의 GPL 버전입니다. TeX는 Donald Knuth의 정교한 조판 시스템입니다. 흔히, 이 마크업 언어들에 넘길 인자나 옵션들을 쉘 스크립트로 처리를 해서 편하게 씁니다.

lex, yacc

구문 분석기(lexical analyzer)인 lex는 패턴 매칭을 위한 프로그램을 만들어 냅니다. 리눅스 시스템에서는 이 명령어의 비특허 버전인 flex로 바뀌었습니다.

yacc 유틸리티는 스펙셋에 의거한 파서를 만들어 냅니다. 리눅스 시스템에서는 이 명령어의 비특허 버전인 bison으로 바뀌었습니다.

 

파일 아카이브 명령어 

 

tar

유닉스의 표준 아카이브(archive) 유틸리티. 원래는 Tape ARchiving 프로그램에서 왔는데, 이 프로그램은 테입 드라이브부터 보통 파일, 심지어는 표준출력(예 4-3 참고)까지 포함하는 모든 종류의 디바이스에 대해서 모든 종류의 아카이브를 다룰 수 있도록 만들어 졌습니다. GNU tar는 오래전부터 gzip 압축을 다룰 수 있는 옵션이 패치되어 있었는데, tar czvf archive-name.tar.gz * 라고 하면 하위 디렉토리를 포함한 모든 파일을 묶어서 압축하라는 뜻입니다(도트파일은 제외).

유용한 tar 옵션 몇 가지:

  1. -c 만들기(새 아카이브)
  2. --delete 지우기(아카이브에 들어 있는 파일)
  3. -r 덧붙이기(파일을 아카이브로)
  4. -t 목록(아카이브 내용)
  5. -u 아카이브 업데이트
  6. -x 뽑아내기(아카이브에 들어 있는 파일)
  7. -z 아카이브를 gzip 으로 압축

shar

쉘 아카이브 유틸리티. 쉘 아카이브 파일은 실제로는 #!/bin/sh 헤더와 아카이브를 풀기 위한 명령어들로 이루어진 쉘 스크립트로써, 압축되지 않은 파일들이 쭉 붙어 있는 파일입니다. shar 아카이브는 아직도 인터넷 뉴스 그룹에서 볼 수 있는데 여기 말고 다른 곳에서는 tar/gzip 때문에 거의 안 씁니다. shar 아카이브는 unshar 명령어로 풀어 줍니다.

 

ar

주로 바이너리 오브젝트 파일 라이브러리에서 쓰이는 아카이브를 위한 생성, 조작 유틸리티.

 

cpio

이 특화된 아카이브 복사 명령어(copy input and output)는 tar/gzip 때문에 이제 거의 안 쓰이지만 디렉토리 트리를 옮기려는 경우등의 쓰임새가 아직 남아 있습니다.

 

gzip

표준 GNU/UNIX 압축 유틸리티로서, 성능이 떨어지고 특허가 걸려 있는 compress를 대신합니다. 압축 풀기 명령어는 gunzip으로써, gzip -d와 같습니다.

zcat 필터는 gzip으로 묶인 파일의 압축을 풀어 표준출력으로 내보내기 때문에 파이프의 입력이나 재지향에서 쓰일 수 있습니다. 즉, 실제로는 입축 파일에 대해서 동작하는 cat이라고 보면 됩니다(옛날 compress 로 묶인 파일도 포함). zcat gzip -dc와 같습니다.

bzip2

또 다른 압축 유틸리티로써, 특별히 크기가 큰 파일에 대해서는 gzip보다 효율적입니다. bzip2에 대한 압축풀기 명령어는 bunzip2입니다.

 

file

파일 종류를 구분지어 주는 유틸리티, file filename이라고 치면 ascii text이 data같은 file-name에 대한 스펙을 알려줍니다. 이 명령어는 Linux/Unix 배포판에 따라 /usr/share/magic이나 /etc/magic, /usr/lib/magic등에서 매직 넘버를 참고해서 파일 스펙을 알려줍니다.

 

-f 옵션을 쓰면 파일이름의 목록이 들어 있는 지정된 파일을 분석하면서 배치 모드로 동작합니다. -z 옵션은 대상 파일이 압축된 파일일 경우 강제로 압축이 풀린 상태의 파일 타입을 분석해 줍니다.

basename

 

파일명에서 경로 정보를 떼어내고 오직 파일 이름만 보여줍니다. basename $0 이라고 하면 스크립트는 자기가 쉘에서 불린 자기 이름을 알 수 있습니다. 스크립트에 필요한 인자가 없이 실행되는 경우에 "사용법" 메시지를 찍을때 쓸 수 있습니다.

 

echo "사용법:  `basename $0` arg1 arg2 ... argn"

 

dirname

 

파일명에서 basename을 떼어내고 오직 경로 정보만 보여줍니다.

참고 : basename과 dirname은 어떤 문자열에 대해서도 동작합니다. 이 명령어들에 넘겨줄 인자는 꼭 실제로 존재하는 파일이 아니여도됩니다.

 

make

바이너리 패키지를 빌드 및 컴파일 해주는 유틸리티. 소스 파일에서 추가 변경 사항이 발생하면 정해진 동작을 하도록 하는데 쓰입니다.

make 명령어는 파일 의존성과 수행할 동작이 들어있는 Makefile을 바탕으로 동작합니다.

 

more, less

텍스트 파일이나 스트림을 표준출력으로 한 번에 한쪽씩 표시해 주는 페이저입니다.스크립트의 출력을 위한 필터로 쓸 수 있습니다.

 

 

 

 

 

728x90

'쉘스크립트' 카테고리의 다른 글

11.~ / 내부명령어  (0) 2022.03.04
10~ / 루프  (0) 2022.03.03
9~ / 변수 재검토  (0) 2022.03.03
8~/ 9~/ 연산자, 변수 재검토  (0) 2022.03.03
7~ 테스트  (0) 2022.03.03
728x90

내부 명령(builtin) 은 Bash 툴 셋에 포함된 명령어로 말 그대로 bulit in(고유의, 붙박이의)된 명령어입니다. 내부 명령은 시스템 명령어와 이름이 같을 수도 있지만 이런 경우는 Bash가 내부적으로 다시 구현해 놓은 것입니다. [1] 예를 들어, 하는 일이 거의 동일한 bash의 echo /bin/echo와 다릅니다.

키워드(keyword)는 예약된 낱말, 토큰, 연산자를 말합니다. 키워드는 쉘에서 특별한 의미를 가지면서, 쉘 문법을 형성해 줍니다. 예를 들면, "for", "while", "!"가 키워드입니다. 내부 명령(builtin)과 비슷하게 키워드도 Bash 내부에 하드코드(hard-coded)되어 있습니다.

 

echo

변수나 표현식을 표준출력으로 출력(예 5-1 참고).

printf

 

printf는 형식화된 출력을 해주는 명령어로서, echo의 확장판입니다. C 언어의 printf보다 기능이 제한된 변종으로, 문법은 C와 약간 다릅니다.

 

printf format-string... parameter...

/bin/printf나 /usr/bin/printf의 bash 내장 명령 버전입니다. 더 자세한 내용은 printf(시스템 명령어)의 맨 페이지를 참고하세요.

 

read

변수값을 표준입력에서 "읽어 들입니다." 즉, 키보드에서 사용자의 입력을 받아 처리합니다. -a 옵션을 주면 read는 변수를 배열로 받아 들입니다(예 26-2 참고).

 

예 11-3. read로 여러줄의 입력 넣기

read 명령어는 프롬프트를 보여준 다음 ENTER없이 키누름을 받아 들이는 재밌는 옵션을 갖고 있습니다.

read 명령어는 프롬프트를 보여준 다음 ENTER없이 키누름을 받아 들이는 재밌는 옵션을 갖고 있습니다.

read 명령어는 표준입력으로 재지향된 파일에서 변수값을 "읽을" 수도 있습니다. 입력 파일이 한 줄 이상이라면 첫 번째 줄만 변수로 할당됩니다. read가 하나 이상의 매개변수를 갖고 있다면 각 변수는 공백 문자로 구분되는 연속적인 문자열로 할당됩니다. 조심하세요!

stack의 개념을 도입

 

pushd, popd, dirs

이 명령어들은 작업 디렉토리를 즐겨찾기에 기억시켜주는 메카니즘으로, 디렉토리간에 순서대로 왔다 갔다 할 수 있게 해 줍니다. 디렉토리 이름을 기억하기 위해서 푸쉬다운 스택을 사용합니다. 옵션을 줘서 디렉토리 스택에 대해서 다양한 조작을 할 수 있습니다.

 

pushd dir-name dir-name을 디렉토리 스택에 넣고 동시에 현재 디렉토리를 그 디렉토리로 옮겨 줍니다.

 

popd는 디렉토리 스택의 제일 위에 있는 디렉토리를 지우고(pop) 동시에 현재 디렉토리를 그 디렉토리로 옮겨 줍니다.

 

dirs은 디렉토리 스택의 목록을 보여줍니다 ($DIRSTACK과 같음). pushd popd가 성공한다면 dirs가 자동으로 불립니다.

디렉토리 이름을 하드 코딩하지 않고 디렉토리를 여기 저기로 옮겨 다녀야 하는 스크립트가 이 명령어를 쓰면 아주 좋습니다. 스크립트 내에서 디렉토리 스택의 내용을 담고 있는 $DIRSTACK 배열 변수에 묵시적으로 접근이 가능하기 때문에 주의해야 합니다.

 

let 

 

let 명령어는 변수에 대해서 산술 연산을 수행합니다. 많은 경우에 있어서 expr보다 좀 간단한 기능을 수행합니다.

eval

eval arg1 [arg2] ... [argN]

목록에 들어 있는 인자를 명령어로 변환(스크립트 안에서 코드를 만들어 낼 때 유용함).

 

예 11-7. eval의 효과 보여주기

위 스크립트에서

tr a-z n-za-m [치환 명령어]

 

[abcdefghijklmnopqrstuvwxyz]

[nopqrstvwxyzabcdefghijklmn]

 

f -> s

o -> b

o -> b

 

set

 

set 명령어는 내부 스크립트 변수값을 바꿔줍니다. 스크립트의 행동을 결정하는 옵션 플래그를 키거나 끄는 역할에 쓰이기도 하고 특정 명령어의 결과(set `command`)를 위치 매개변수로 리셋 시켜서 스크립트가 그 명령어의 결과를 필드별로 파싱할 수 있게 해 줍니다.

 

 

예 11-10. 위치 매개변수와 set 쓰기3

unset

unset 명령어는 쉘 변수를 효과적으로 (null)로 세트를 해서 그 변수를 지우는 효과를 가져옵니다. 이 명령어는 위치 매개변수에 대해서 동작하지 않는 것에 주의하세요.

unset PATH 하는경우 모든 명령어가 안먹음 .. (주의)

 

/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/rsccmw/.local/bin:/home/rsccmw/bin

 

export 명령어를 통해서 환경변수를 다시 원래값으로 복구해줘야 정상적으로 돌아온다.. 

 

export

 

 

export 명령어는 현재 실행중인 스크립트나 쉘의 모든 자식 프로세스가 변수를 사용할 수 있게 해 줍니다. 불행하게도 스크립트나 쉘을 부른 부모 프로세스에게 변수를 다시 export 할 방법은 없습니다. export 시스템 구동(startup) 파일에서 환경 변수를 초기화하고 그 다음에 생성될 사용자 프로세스들이 그 변수에 접근할 수 있게 해주는 아주 중요한 용도로 쓰입니다.

 

declare, typeset

declare  typeset 명령어는 변수의 특성을 지정하거나 제한해 줍니다.

 

readonly

declare -r과 같은 역할을 하는 명령어로서, 어떤 변수를 읽기 전용으로 만들어 주는 것인데, 결국 상수로 쓰겠다는 것입니다. 이런 변수값을 바꾸려고 한다면 에러 메세지를 만나게 됩니다. C 언어의 const 형지정자와 비슷한 것으로 보면 됩니다.

 

getopts

이것은 아주 강력한 도구로서 명령어 줄에서 스크립트로 넘어온 인자를 파싱해 줍니다. C 프로그래머들에게 익숙한 getopt 라이브러리 함수의 bash 버전입니다. 스크립트로 넘어오는 여러개의 옵션 [2] 과 그 해당 인자들을 처리해줍니다(예를 들면, scriptname -abc -e /usr/local).

 

getopts는 내부적으로 두 개의 변수를 사용합니다. $OPTIND(OPTion INDex)는 인자 포인터이고 $OPTARG(OPTion ARGument)는 옵션에 딸려 넘어오는 해당 인자(선택적)입니다. 선언 태그의 옵션 이름뒤에 콜론이 있으면 해당 인자가 있다는 뜻입니다.

 

getopts는 보통 while 루프와 같이 써서 옵션과 인자를 한 번에 하나씩 처리하고 $OPTIND 변수값을 하나씩 줄여서 그 다음을 처리하게 합니다.

참고:

  1. 명령어 줄에서 인자앞에는 빼기(-)나 더하기(+)를 적어 줘야 하는데 이 접두사가 있어야 getopts가 명령어 줄 인자를 옵션으로 인식할 수 있습니다. 실제로는, -나 +가 빠져 있는 첫번째 인자를 만나면 바로 종료하게 됩니다.
  2. getops는 표준 while 루프와 약간 다른 형태로 조건 대괄호가 빠져 있는 형태입니다.
  3. 예전의 getopt 대신 getopts가 새롭게 쓰입니다.
 #!/bin/bash
## 도움말 출력하는 함수
help() {
        echo "splt [OPTIONS] FILE"
                echo "    -h         도움말 출력."
                echo "    -a ARG     인자를 받는 opt."
                echo "    -b ARG     인자를 받는 opt2."
                exit 0
}
while getopts "a:b:h" opt
do
case $opt in
a) arg_a=$OPTARG
echo "Arg A: $arg_a"
;;
b) arg_b=$OPTARG
echo "Arg B: $arg_b"
echo "$arg_b"
;;
h) help ;;
?) help ;;
esac
done

getopt를 사용하는 이유는

 

1. 다양한 입력 값이 존재할 경우 사용자와 개발자의 편의를 보장하기 위함 이고

2. 스크립트를 보다 체계적으로 관리할 수 있기 때문입니다.

 

가장 중요한 부분은 아래의 구분인데

 

while getopts "a:b:h" opt

 

보통 다음과 같은 형식을 주로 사용하고 getopt는 첫번째 파라미터로 옵션으로 사용될 문자열을 입력 받고 다음에는 옵션으로 활용되는 변수를 사용합니다.

 

getopt를 사용할 때 주의해야 할 점은 ":" 입니다. 기존적으로 getopt는 한개의 문자만을 구분자로 사용하며 사용할 문자열 뒤에 ":"을 붙이게 되면 뒤에 Value가 붙게 된다는 것을 의미합니다

 

스크립트 실행 결과는 다음과 같습니다




스크립트 동작

source. (점(dot) 명령어)

 

이 명령어가 명령어 줄에서 불린다면 해당 스크립트를 실행 시킵니다. 스크립트에서 source file-name이라고 불린다면 file-name을 읽어 들일 것입니다. C/C++의 #include 지시자와 같은 역할을 합니다. 여러개의 스크립트가 공통으로 쓰이는 데이타 파일이나 함수 라이브러리를 써야 할 경우같은 상황에서 유용합니다.

예 11-14. 데이타 파일 "포함하기"

data file

exit

 

스크립트를 무조건 끝냄. exit는 정수값을 인자로 받아서 쉘에게 스크립트의 종료 상태를 알려줄 수도 있습니다. 아주 간단한 스크립트가 아니라면 스크립트의 마지막에 exit 0처럼 성공적인 실행을 알려 주는 것은 아주 좋은 습관입니다.

참고: 만약에 exit가 인자 없이 쓰인다면 그 스크립트의 종료 상태는 exit를 제외하고 가장 마지막에 실행된 명령어의 종료 상태로 됩니다.

exec

이 쉘 내부 명령은 현재의 프로세스를 주어진 명령어로 대치시킵니다. 보통은 쉘이 어떤 명령어를 만나면 그 명령어를 실행하기 위해서 자식 프로세스를 포크 [3] 시킵니다. 하지만 exec 내장 명령은 포크를 하지 않고 exec된 그 명령어로 쉘 자체를 대치시킵니다. 그렇기 때문에 스크립트에서 이 명령어가 쓰이면 exec된 명령어가 종료할 때 스크립트가 강제로 종료됩니다. 이런 이유로, exec을 스크립트에서 쓰려면 아마도 제일 마지막 명령어로 써야 할 겁니다.

 

exec는 또한 파일 디스크립터를 재할당 할 때도 쓰입니다. exec <zzz-file은 표준입력을 zzz-file으로 바꿔줍니다(예 16-1 참고).

shopt

이 명령어는 쉘이 실행중에 옵션을 바꿀 수 있게 해 줍니다(예 24-1 예 24-2 참고). 이는 종종 Bash 시스템 구동 파일(startup files)에서 쓰이는 데 일반 스크립트에서도 쓰일 수 있습니다. 이 명령어는 bash 버전 2나 그 다음 버전부터 쓸 수 있습니다..

 

명령어true

단순히 성공적(0)인 종료 상태를 리턴하는 명령어.

false

단순히 실패한 종료 상태를 리턴하는 명령어..

type [cmd]

외부 명령어인 which와 비슷하게 주어진 "cmd"의 완전한 경로명을 보여 줍니다. 하지만, which와는 다르게 type는 bash 내장 명령입니다. 유용한 옵션인 -a를 주면 주어진 "cmd" 키워드인지 내장 명령인지를 알려주고 똑같은 이름의 시스템 명령어가 있다면 그 위치도 알려줍니다.

hash [cmds]

주어진 명령어의 경로명을 쉘 해쉬 테이블에 저장해서 그 명령어가 다시 불릴 때 $PATH에서 찾지 않도록 해줍니다. hash를 인자 없이 쓰면 자신이 해쉬하고 있는 목록을 보여줍니다. -r 옵션은 해쉬 테이블을 초기화 합니다.

help

help 명령어는 쉘 내장 명령에 대한 간략한 사용법을 알려줍니다. whatis와 동일하지만 내장 명령에 대해서 쓰인다는 점이 다릅니다.

 

disown

쉘의 활성화 작업 테이블에서 특정 작업을 지워버립니다.

fg, bg

fg 명령어는 백그라운드에서 실행중인 작업을 포그라운드로 돌려 놓습니다. bg 명령어는 중지되어 있던 작업을 백그라운드에서 다시 돌게 합니다. fg bg에 작업 번호가 주어지지 않는다면 현재 돌고 있는 작업에 대해서 동작합니다.

wait

백그라운드로 실행중인 모든 작업이나 옵션으로 주어진 특정 작업 번호나 프로세스 아이디가 끝날 때까지 스크립트 실행을 중단 시킵니다. 자신이 기다리고 있던 명령어의 종료 상태를 리턴합니다.

백그라운드 작업이 끝나기 전에 스크립트가 끝나는 것(무서운 고아 프로세스를 만들어 낼 수 있습니다)을 피하기 위해 wait 명령어를 쓸 수도 있습니다.

예 11-16. 작업을 계속 해 나가기 전에 프로세스가 끝나길 기다리기.

suspend

Control-Z 와 비슷한 효과를 갖고 있지만 이것은 쉘을 suspend 시킵니다(쉘의 부모 프로세스는 적당한 시간이 지나면 실행을 재개할 것입니다).

logout

로그인 쉘을 빠져나가기. 옵션으로 종료 상태를 지정해 줄 수 있습니다.

times

명령어를 실행하는 데 쓰인 시스템 시간에 대한 통계 정보를 다음 형식으로 보여줍니다.

 
제한된 범위의 값만을 보여주기 때문에 쉘 스크립트를 프로파일하거나 벤치마크하는데 쓰이지 않습니다.kill

적당한 종료 시그널을 주어 프로세스를 강제로 끝내게 합니다(예 13-4 참고).

참고: kill -l이라고 하면 가능한 모든 시그널을 볼 수 있습니다. kill -9은 간단한 kill만으로 죽기를 거부하는 지독한 프로세스를 "확실히 죽여줍니다". 가끔은, kill -15로도 될 때가 있습니다. 부모가 종료된 "좀비 프로세스"는 죽일 수 없지만(이미 죽은 것을 죽일 수는 없습니다), 보통은 init이 이런 상태를 금방 청소해 줄 것입니다.

command

command 명령어 지시어는 "명령어"에 대한 별칭이나 함수 찾기를 하지 않습니다.

참고: 이는 스크립트의 명령어 처리에 영향을 주는 세 가지 지시어중 하나이고, 나머지 두 개의 지시어는 builtin enable입니다.

builtin

builtin BUILTIN_COMMAND라고 치면 "BUILTIN_COMMAND"를 쉘 내장 명령어로 실행 시키면서 잠시 같은 이름을 가진 함수와 외부 시스템 명령어에 대한 기능을 꺼버립니다.

enable

이 명령어는 쉘 내장 명령을 키거나 끄는 역할을 합니다. 예를 들어, enable -n kill이라고 하면 쉘 내장 명령인 kill의 기능을 끄고 다음부터 나오는 모든 kill에 대해서는 /bin/kill을 실행 시킵니다.

-a 옵션을 주면 모든 쉘 내장 명령에 대해 각각이 사용 가능한 지를 보여줍니다. -f filename 옵션은 enable 명령어가 미리 컴파일된 오브젝트 파일에서 공유 라이브러리(DLL) 모듈을 내장 명령으로 로드하도록 해 줍니다. [1].

autoload

이 명령어는 ksh autoloader를 Bash로 포팅한 것입니다. autoload를 함수 선언시에 같이 쓰면, 그 함수가 처음 불릴 경우에 외부 파일에서 로드합니다. [2] 이렇게 하면 시스템 리소스를 절약해 줍니다.

조심할 것은 autoload는 Bash 설치시 기본으로 깔리지 않기 때문에 enable -f(위를 참조)로 로드를 해 주어야 합니다.

표 11-1. 작업 ID(Job Identifiers)

표시뜻
%N [N] 작업 숫자
%S S 문자로 시작하는 작업을 부름(명령어줄)
%?S S 문자를 포함하는 작업을 부름(명령어줄)
%% "현재" 작업(포그라운드에서 중지된 최근 작업이나 백그라운드로 막 돌기 시작한 작업)
%+ "현재" 작업(포그라운드에서 중지된 최근 작업이나 백그라운드로 막 돌기 시작한 작업)
%- 마지막 작업
$! 최근 백그라운드 프로세스
728x90

'쉘스크립트' 카테고리의 다른 글

12.~/ 외부 필터 , 프로그램 , 명령어  (0) 2022.03.04
10~ / 루프  (0) 2022.03.03
9~ / 변수 재검토  (0) 2022.03.03
8~/ 9~/ 연산자, 변수 재검토  (0) 2022.03.03
7~ 테스트  (0) 2022.03.03
728x90

루프란 루프 제어 조건이 참인 동안에 여러 명령어들을 반복적으로 수행하는 코드 블럭입니다.

 

for 루프

 

for (in)

 

다음은 기본적인 루프문인데 C의 루프문과는 상당한 차이를 보입니다.

 

for arg in [list]

do

command...

done

list 인자에는 와일드 카드가 올 수도 있습니다.

do for와 한 줄에 쓴다면 list 뒤에 세미콜론이 있어야 합니다.

for arg in [list] ; do

 

예 10-11. C 형태의 for 루프

 

 

while

 

while은 루프 최상단에서 특정 조건을 확인하면서 그 조건이 참일 동안 루프를 계속 돌도록 해 줍니다(종료 상태 0을 리턴합니다).

while [condition]
do
command...
done

for/in 경우처럼 do를 조건 테스트문과 같은 줄에 쓰려면 세미콜론을 써 줘야 합니다.

while [condition] ; do

 

 if [ ! -e "$file" ]       # 파일이 존재하는지 확인.

-e 옵션 : 파일이 존재하면 참이므로 앞에 ! (부정을뜻하는) 연산자를 넣어줌으로써

파일이 존재하지않는다면 ~ing 이 된다.

 

for 문에서 in [list]을 안 써주면 명령어 줄에서 넘어온 인자인 $@에 대해서 동작합니다. 이런 식으로 처리하는 멋진 예제를 보려면 예 A-11를 참고하세요.

예 10-5. in [list]가 빠진 for 

예 10-6. for 문의 [list]에 명령어 치환 쓰기

이진 파일에서 일치하는 문자열 찾아내기

 

$( find $directory -type l )

 

for 

do

 command...

done | sort

 

C 형태의 문법을 쓰는 while 루프

until

 

until은 루프 최상단에서 특정 조건을 확인하면서 그 조건이 거짓일 동안 루프를 계속 돌도록 해 줍니다(while 과 반대)

 

until [condition-is-true]

do

command...

done

 

주의할 점은 until이 몇몇 프로그래밍 언어에서 비슷한 형태와는 다르게 루프 처음에서 끝내는 조건을 검사한다는 것 입니다.

for/in 경우처럼 do를 조건문과 한 줄에 같이 쓰려면 세미콜론을 적어줘야 합니다.

until [condition-is-true] ; do

예 10-17. until 루프

10.2. 중첩된 루프

중첩된 루프는 루프 안에 루프가 들어 있는 형태를 말합니다. 바깥쪽 루프의 매 단계마다 안쪽 루프를 돌리는데, 이 전체 동작은 바깥쪽 루프가 끝날 때까지 계속 됩니다. 당연한 얘기지만, 안쪽 루프나 바깥쪽 루프에서 break가 나타나면 전체 동작을 중단시킵니다.

예 10-18. 중첩된 루프

 

 

루프의 동작에 영향을 미치는 명령어들break, continue

break continue 루프 제어 명령어 [1] 는 다른 프로그래밍 언어들과 정확히 같은 동작을 합니다. break 명령어는 자신이 속해 있는 루프를 끝내고, continue는 해당 루프 사이클 내에 남아 있는 나머지 명령어들을 건너 뛰고 다음 단계의 루프를 수행합니다.

 

break 명령어는 매개변수를 받을 수도 있습니다. 매개변수 없는 break는 자신이 속해 있는 제일 안쪽 루프를 끝내지만, break N N 레벨의 루프를 빠져나갑니다.

예 10-20. 여러 단계의 루프에서 탈출하기

continue 명령어도 break와 비슷하게 매개변수를 받아 들일수 있습니다. 매개변수 없는 continue는 자신이 속한 루프의 현재 작업을 끝내고 다음번으로 건너 뛰지만 continue N은 자신이 속한 루프 레벨의 모든 단계를 건너 뛰고 N 레벨 위에 속하는 루프의 다음 단계로 건너 뜁니다.

예 10-21. 더 상위 루프 레벨에서 계속하기(continue)

case select는 코드 블럭을 반복해서 수행하지 않기 때문에 기술적으로 루프가 아닙니다. 하지만 루프가 하는 것처럼 특정 블럭의 위나 아래에서 주어진 조건에 따라 프로그램 흐름을 조정해 줍니다.

 

case (in) / esac

case는 C/C++의 switch와 동일합니다. 조건에 따라 여러개의 코드 블럭중 하나로 분기할 수 있게 해주는데, 여러개의 if/then/else의 간단한 표기법처럼 동작하기 때문에 메뉴같은 것을 만들 때 적당합니다.

 

 

case "$variable" in

"$condition1" )
command...
;;

"$condition2" )
command...
;;

 

esac

 

참고:

  • 낱말 조각남(word splitting)이 일어나지 않기 때문에 꼭 variable을 쿼우팅 하지 않아도 됩니다.
  • 각 조건들은 오른쪽 괄호, )로 끝납니다.
  • 각 조건 블럭은 이중 세미콜론, ;;.
  • 전체 case 블럭은 esac로 끝납니다(case를 거꾸로 스펠링).

* ) # 는 default 옵션

    # 그냥 리턴을 쳐도 여기로 반환

 

 

 

명령어줄 매개변수를 확인하려고 할 때, 아주 창의적인 방법으로 case를 사용하는 법을 보여 드리겠습니다.

예 10-24. case용 변수를 만들기 위해서 명령어 치환 쓰기

예 10-25. 간단한 문자열 매칭

select

select는 Korn 쉘에서 따온 것인데 메뉴를 만들때 쓸 수 있습니다.

select variable [in list]
do
command...
break
done

 

사용자가 list에 있는 것중 하나를 고를 수 있게 해 줍니다. 기본적으로 PS3(#? ) 프롬프트를 쓰고 이 값은 바꿀 수 있다는 것에 주의하기 바랍니다..

 

in list를 안 쓰면 select는 스크립트나 select를 포함하고 있는 함수로 넘어온 명령어 줄 인자($@)을 사용합니다.

in list가 빠졌을 경우를

for variable [in list]

의 경우와 비교해 보세요.

728x90

'쉘스크립트' 카테고리의 다른 글

12.~/ 외부 필터 , 프로그램 , 명령어  (0) 2022.03.04
11.~ / 내부명령어  (0) 2022.03.04
9~ / 변수 재검토  (0) 2022.03.03
8~/ 9~/ 연산자, 변수 재검토  (0) 2022.03.03
7~ 테스트  (0) 2022.03.03

+ Recent posts