반응형
SMALL

'전체 글'에 해당되는 글 209건

반응형
LIST
반응형
SMALL


17년에 들어와서 랜섬웨어 주의경보가 발령됐다. 미국에서 처음 발견된 이 소프트웨어 악성코드는 전 세계로 뻗어나가고 있다. 이 바이러스에 감염되면 위와 같은 메시지가 뜨면서 컴퓨터에 있는 모든 문서가 암호화가 걸리고 해커들은 암호를 풀어준다는 대가로 돈을 요구하는 수법으로 사용자들이 많은 피해를 보고 있다. 사우디아라비아쪽에서도 랜섬웨어와 전쟁을 벌이고 있으며 우리나라도 예외는 없다. 이로 인해 당장 업무 정상화가 필요한 기업들은 해커가 요구하는 사이버머니를 지불하고 문제를 해결하는 사례도 빈번히 발생하고 있다 지금 현재로썬 딱히 치료프로그램도 없어서 더 애를 먹고 있다. 그나마 알약이 어느정도 방어를 해주고는 있는데 완벽하게 랜섬웨어를 방어해주진 못하는게 현실이다. 랜섬웨어를 이용해서 사업을 하는 사람들까지 생겨난다고 하니 문제는 더 심각하다. 


한국 벤처기업 CIDISK의 조성곤 대표가 랜섬웨어의 피해 사례에 대해 설명하고 있다.


현재 우리나라 벤처기업인 CDISK 조성곤 대표가 "중요 문서를 백업하는 방식으로 USB나 CD, DVD 등의 외장하드 이용 방법과 클라우드 저장 방식이 이용되고 있다"며"하지만, 어느 것도 백업을 하는 동안의 감염까지는 막을 수 없는 한계가 있다"고 말했다. 랜섬웨어는 치료프로그램이 개발되고 있는 중이어서 철저한 예방을 할 수 밖에 없는게 현실이다. 이어서 CDISK가 개발한 신기술을 발표했는데 스텔스영역을 활용했다는게 핵심이었다. USB나 외장하드의 디스크에 바이러스가 감지할 수 없는 스텔스 영역을 만들고, 중요 문서를 보내 저장하는 방식이다. 스텔스 영역은 바이러스가 인식할 수 없는 네임 스페이스이기 때문에 격리된 구역이고, 이 곳에서는 저장과 편집도 할 수 있다. 현재 실리콘밸리 미국 보안 전문가들도 인정하고 있는 기술이라고 한다. 하루빨리 랜섬웨어를 방어할 수 있는 프로그램이 나와 더이상 기업들이 문서암호화로 인해 피해를 보는 경우가 없으면 하는 바램이며 사용자들이 철저한 예방으로 랜섬웨어를 최대한 방어를 해야한다.


<사진출저: 네이버지식in, 한국경제>

반응형
LIST
블로그 이미지

만년필석사

,
반응형
SMALL



최근 한글문서 취약점을 이용해 정보를 탈취하는 악성코드가 유포돼 국내 사용자들의 주의가 필요하다고 했다. 이번에 발견된 한글문서 악성코드는 ‘북한민주화와 민주주의적 전략.hwp’의 파일명으로 이메일을 통해 유포됐다. 해당 문서를 열람할 경우 정보탈취 악성코드에 감염되어 PC 내의 정보들이 외부로 전송된다. 유포된 한글문서는 취약점을 이용해서 정상 프로그램인 '윈도우스크립트호스트' 프로그램을 실행시키며 이후에 해당 프로세스에 정보탈취 악성코드를 인입시키는 방식으로 동작하고 탈취돈 정보를 국내의 한 쇼핑몰 서버로 전송시킨다. 해당 악성코드는 감염된 PC의 정보 및 PC 화면을 캡처한 이미지 파일을 서버로 전송한다. 또한 추가로 악성코드를 다운로드하는 기능이 포함돼 있어 해커가 추가로 악성 행위를 수행하는 악성코드를 유포해 동작시킬 수 있다. 다행히 백신은 있어서 '바이로봇 에이피트 쉴드'를 통해 사전차단 할 수 있고 바이로봇 백신제품에서도 탐지하고 치료가 가능하다고 한다. 트로이목마바이러스 유포과정과 약간 흡사해서 함부로 이상한파일을 열지 않는게 좋을 것 같다. 16년 9월부터 17년 1월까지의 동향을 보면 이메일을 이용해서 파일을 전송시켜 악성코드를 유포하는 수법이 많이 등장하고 있는 것 같다. 공격형태도 매우 지능적이고 교묘해서 사용자들에 대한 각별한 주의가 필요할 것 같다.

<2017.01.27> 네이버 뉴스 보안 동향 참조

반응형
LIST
블로그 이미지

만년필석사

,
반응형
SMALL

오늘은 이중동작모드에 대해 포스팅해보려고 한다. 이걸 이해하는데 솔직히 좀 시간이 걸렸다. 생소한 용어기도 하고.. 전개되는 과정이 생각보다 많이 복잡해서 개인적으로 시간이 좀 걸렸다. 


1. 이중동작모드란?


- 쉽게 말해 운영체제를 보호하기 위한 기법으로 사용자모드와 커널모드 이 2가지로 분류가 된다. 사용자모드에서 불법적인 명령을 통해 운영체제를 해킹하고 시스템의 위협을 방지하기 위해 사용자모드와 커널모드로 분류해서 운영체제를 운영할 수 있게 했다.

- 사용자모드에서 불법적인 명령을 실행하게 되면 하드웨어는 운영체제로 트랩을 발생시키게 되면서 커널모드에 접근할 수 없다.


2. 이중동작모드의 구조?


<출저: operating system concept>


- 사용자모드와 커널모드로 구분할 수 있으며 운영체제를 위한 작업과 사용자를 위한 작업을 할 수 있다. 모드비트라는 비트가 추가되었는데 하나의비트가 현재의모드를 나타내기 위해 추가되었다. 사용자모드로 전환되면 모드비트가 1이 되고 커널모드로 전환되면 모드비트는 0이된다.

- 컴퓨터시스템에서 사용자 응용을 위해 사용되는 거라면 사용자모드로 유지하게 되지만 사용자응용이 운영체제로부터 서비스를 요청하게 된다면 커널모드로 전환이 된다.(모드비트가 0이됨)

- 또하나 공부한 것은 시스템 부팅시 하드웨어는 커널모드에서 시작되는데 그다음은 운영체제가 적재되고 사용자모드에서 사용자프로세스가 시작되게 된다. 트랩이나 인터럽트가 발생할때마다 하드웨어는 커널모드로 전환을 하게 된다. 그래서 대표적으로 컴퓨터가 제어를 얻을때 항상 커널모드로 있게 된다.

- 사용자모드에서 불법적인 명령을 실행하지 못하게 해놓음으로써 하드웨어는 커널모드에서만 특정한 명령이 실행될 수 있게끔 해놨다. 결국 해커들이 시스템쪽 해킹을 하려면 커널모드 보안부터 뚫어야 가능하다는 이야기인데 과연 빌게이츠가 그렇게 허무하게 뚫리게 윈도우os를 만들었을지는 상상에 맡기고 싶었다.

- 결론적으로 사용자모드에서 특권명령을 시도하려고 들면 하드웨어는 이를 실행하지 않고 불법명령으로 간주해버리고 운영체제에 트랩을 건다. 


3. 시스템 호출이란?

- 응용프로그램의 요청에 따라 커널에 접근하려는 인터페이스

- 시스템호출은 컴퓨터시스템의 처리기가 지원하는 기능에 따라 다양하게 호출된다.

- 운영체제에 의해 실행될 동작을 사용자 프로세스가 요청할 수 있게 하는것이 시스템 호출이다.

- 인터럽트 벡터의 특정위치로 트랩을 거는 형태를 취한다.


* 커널모드에서 시스템호출을 받게 되면 어떤 인터럽트가 발생이 되었는지, 어떤 명령이 왔는지 인지하고 검사를 하는 과정을 거친다. 이때 전달된 인자가 사용자 프로그램이 요청하는 서비스 타입을 표시하게 된다. 커널은 항상 이렇게 정확하게 인자를 합법적인지 검증하고 검사하는 절차를 거치고나서 제어를 시스템호출 다음 명령으로 복귀시킨다.




반응형
LIST

'운영체제 ' 카테고리의 다른 글

명령해석기  (0) 2017.01.30
운영체제서비스  (0) 2017.01.30
멀티프로세싱(Multi Processing)이란?  (0) 2016.09.20
임계구역(Critical section)  (0) 2016.09.11
Context Switching  (0) 2016.09.08
블로그 이미지

만년필석사

,

chat개발

Server 2016. 12. 5. 18:20
반응형
SMALL

var avi = require('http').createServer(handler)

    , io = require('socket.io').listen(avi)

    , fs = require('fs')

  

    avi.listen(3000);


function handler (req, res) {

    console.log(__dirname);

}


var userinfo    = [];//클라이언트 전송용

io.sockets.on('connection', function (socket) {

      

      socket.room = "livingRoom";//기본은 livingRoom  이다.

    /* 대화방 전체 입장 */

    socket.on('systemIn', function (data) {

        //console.log(data);

        if(data.name)

        {

            //최초 입장시 아이디/소켓코드 저장

            socket.nickname = data.name;

            var obj = {socket_id:socket.id, nickname:data.name, room:socket.room};

            userinfo.push(obj);

            io.sockets.emit('systemIn',data);

        }

    });

    

    /* 대화방 나가기 */

    socket.on('systemOut', 

        function (data) 

        {

            socket.emit("systemOut", data);

            socket.broadcast.emit("systemOut", data);

        });

    

    /* room 으로 입장 */

    socket.on('switchRoom', 

        function(newroom) {

        var data = {};

        //사용자  룸 변경

        replaceRoom(newroom);

            

        socket.leave(socket.room);

        // join new room, received as function parameter

        socket.join(newroom);

        socket.emit('updatechat', 'SERVER', 'you have connected to '+ newroom);

        data = mkmessageTxt("public", socket.nickname, socket.nickname+'님이 퇴장했습니다.');

        io.sockets.in(socket.room).emit('message', socket.nickname, data);

        // update socket session room title

        socket.room = newroom;

        //socket.broadcast.to(newroom).emit('updatechat', 'SERVER', socket.nickname+' has joined this room');

        data = mkmessageTxt("public", socket.nickname, socket.nickname+'님이 입장했습니다.');

        io.sockets.in(newroom).emit('message', socket.nickname, data);

        

        //현재 방의 사용자 리스트 변경

        refreshUserList();

    });

    


       

    /* 대화시작 */

    socket.on('updatechat', function (data) {

        if(data.type == 'public')

        {

            io.sockets.in(socket.room).emit('message', socket.nickname, data);

        }

        else

        {

            io.sockets.in(socket.room).sockets[socket.id].emit('message',socket.nickname,data);//본인에게 메시지 전달

            io.sockets.in(socket.room).sockets[data.type].emit('message',socket.nickname,data);//귓속말 상대자에게 메시지 전달

        }

    });


    /* 브라우저를 닫은 경우 현재 방에서 퇴장하는 것으로 처리*/

    socket.on('disconnect', function () {

        if(socket.nickname){

            data = mkmessageTxt("public", socket.nickname, socket.nickname+'님이 퇴장했습니다.');

            io.sockets.in(socket.room).emit('message', socket.nickname, data);

            deleteUser();//

        }

    });

    

    /* 현재 채팅방의 사용자 리스트 가져오기 */

    var getRoomUsers = function(){

        var userList = [];

        for (var i in userinfo) {

            if(userinfo[i].room == socket.room){

                userList.push(userinfo[i]);

            }

        }

        return userList;

    }

    

    /* 현재 사용자의 채팅방 변경 */

    var replaceRoom = function(roomname){

        for (var i in userinfo) {

            if(userinfo[i].socket_id == socket.id){

                userinfo[i].room = roomname;

            }

        }

    }

    

    /* 현재 사용자 삭제 (시스템을 떠났을 경우) */

    var deleteUser  = function(){

        for (var i in userinfo) {

            if(userinfo[i].socket_id == socket.id){

                delete userinfo[i];

                userinfo.splice(i, 1)

            }

        }

        refreshUserList();

    }

    

    

    var mkmessageTxt = function(type, nickname, msg){

        var message =   {type : type, name : nickname, message : msg}

        return message;

    }

    

    /* 사용자 목록 갱신 */

    var refreshUserList = function(){

        var userList    = getRoomUsers();

        io.sockets.in(socket.room).emit('systemList',userList);

    }

           

       

 });



<meta charset="UTF-8">

    <title>우리들의 일상</title>

    <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>

    <script src="http://localhost:3000/socket.io/socket.io.js"></script>

    <script type="text/javascript">


    $(function(){

        var nick_name = '';

        var socket = io.connect('http://localhost:3000');

         

        $("#enter").click(function(){

            nick_name = $('#nick_name').val();

            if(nick_name == "")

            {

                alert('닉네임을 입력하세요');

            }

            else

            {

                socket.emit('systemIn',{

                    name : nick_name

                });

 

                $("#door").slideUp(200).delay(200,function(){

                    $("#room").slideDown(200);

                });

            }

                 

        });

         

        $(".room").click(function(){

            var room = $(this).val();

            socket.emit('switchRoom', room);

            $("#room").slideUp(200).delay(200,function(){

                $("#chat").slideDown(200);

            });

        });


 

        socket.on('systemList',function(data){

            $("#nick_lst").empty();

            $("#nick_lst").append('<option value="public">모두</option>');

            for (var i in data) {

                $("#nick_lst").append('<option value="'+data[i].socket_id+'">'+data[i].nickname+'</option>');

            }

        });

         

        socket.on('systemIn',function(data){//전체 시스템에 로그인시(대화방으로는 가기전) 별도 전체 창에서 공지

 

        });

 

        socket.on('systemOut',function(data){//전체 시스템에 로그아웃시(대화방으로는 가기전)

        });

 

        socket.on('message',function(usesrname, data){//전체 시스템에 로그아웃시(대화방으로는 가기전)

            $('#msg').append('<dt>'+usesrname+' : </dt><dd>'+data.message+'</dd>');

            scrollDonw();

        });

 

        $("#txt").keypress(function(ent){

            if(ent.which == 13){

                $("#input").click();

            }

        });

         

        $("#input").bind('click',function(){

            socket.emit('updatechat',{

                type : $("#nick_lst").val(),

                name : nick_name,

                message : $("#txt").val()

            });

            $("#txt").val('');

        });

    });

    function scrollDonw()

    {

        $("#msg").animate({'scrollTop':$("#msg")[0].scrollHeight},200);

    }

    </script>

</head>

<body>


<section id="wrap">

    <header>

    <body style="background-color:powderblue;">


        <h1>이런저런 사는 이야기</h1>

    </header>

    <section>

        <div id="door">

                닉네임 : <input type="text" id="nick_name" value="">   

                <button type="button" id="enter">입장하기</button>

        </div>


        <div id="room">

            대화방선택 :

            <input type="button" class="room" value="10대방"> 

            <input type="button" class="room" value="20대방"> 

            <input type="button" class="room" value="30대방">

            <input type="button" class="room" value="40대방">

            <input type="button" class="room" value="50대방">

            <input type="button" class="room" value="직장인들을 위한방">

            <input type="button" class="room" value="여자들의 방">

        </div>


        <div id="group_select">

        성별:

        <select name="group_select" id="group_select">

        <option value="a">남성</option>     

        <option value="b">여성</option>     


        </select>


        <div id="chat">

            <dl id="msg">

            </dl>

            <div id="edit">

                <select name="nick_lst" id="nick_lst">

                    <option value="public">모두에게</option>

                </select>

                <input type="text" name="txt" id="txt">

                <button id="input">전송</button>

            </div>

        </div>

    </section>

</section>

 

</body>

</html>

반응형
LIST
블로그 이미지

만년필석사

,
반응형
SMALL

이번엔 안드로이드 OS 부팅과정에 대해서 포스팅해보려고한다. 안드로이드 운영체제만큼 중요하다고 생각하는 것이 안드로이드 OS 부팅과정이다. 전체적인 그림은 다음과 같다.




<출저: Google>



1. 커널(Kernel) 부팅


- 전원이 인가되고 부트로더를 통해 리눅스 기반 커널이 제일 먼저 시작된다.

- 커널이 부팅되면 일반적인 리눅스부팅과정처럼 커널 초기화를 수행한다.

- 커널 초기화를 수행하고나서 init 프로세서를 호출한다.


2. init 프로세서 실행


- init 프로세스는 각종 디바이스를 초기화해주고 안드로이드 프레임워크 동작에 필요한 각종 데몬, 컨택스트 매니져 등을 실행하는 역할을 해준다.


** init프로세서가 실행하는 주요 데몬프로세스**


- USB 데몬: usbd

- 안드로이드 디버그 브릿지 데몬: adbd

- 디버그데몬: debuggerd

- 무선 인터페이스 레이어 데몬: rild


3. 컨텍스트 매니저


- 안드로이드의 시스템 서비스를 관리하는 중요한 프로세서다. 

- 카메라, 오디오, 비디오 처리에서부터 애플리케이션 제작에 필요한 API를 제공한다.


4. 미디어 서버

- 오디오출력, 카메라 서비스와 같이 C, C+기반으로 작성되어있는 네이티브 시스템 서비스를 실행하는 역할을한다.

- 미디어 서버가 실행되야 소리가 실행될 수 있다.


5. 자이고트(Zygote), 달빅(Dalvik)

- 자이고트는 안드로이드 애플리케이션의 로딩시간을 단축시키기 위한 프로세스다. 모든 자바 기반 안드로이드 애플리케이션은 자이고트를 통해 포크된 프로세스 상에서 동작되게 된다.

- 달빅 가상머신은 애플리케이션 샌드박스를 만들기 위해 구글이 선택한 기술이며, 모든 자바기반 안드로이드 애플리케이션을 처리해주게 된다.


6. 시스템서버(System Server)

- 시스템서버는 자이고트에서 최초로 포크되어 실행되는 안드로이드 애플리케이션 프로세서이다.

- 로케이션매니져와 같은 자바서비스를 실행한다.(위치추적)

- 추가로 하나 더 설명하자면 바인더 IPC를 통해 자바시스템서비스를 C언어 기반의 서비스매니저에 등록하기위해 자바와 C언어 간의 인터페이스 역할을 하는 JNI를 추가로 이용한다.





이상으로 안드로이드 부팅과정에 대해 포스팅해보았다. 적어도 안드로이드 구성이 어떻게 되있고 부팅과정정도는 알고 써야 진정한 안드로이드 프로그래머가 될 수 있지 않을까 생각한다.

반응형
LIST
블로그 이미지

만년필석사

,
반응형
SMALL

안드로이드 운영체제 구조는 리눅스 커널을 기반으로 만들어졌다. 안드로이드는 코드를 짜는 것도 중요하지만 os자체는 어떻게 구성되어 있는지, 또 그것이 어떤역할을 하는지에 대해 확실히 알 필요성이 있다. 그만큼 이런 구조도 확실하게 알고 있어야 개발이든 보안이든 둘다 가능하다. 




<안드로이드 os의 구조>


안드로이드 os는 굉장히 무거운 os에 속한다. 리눅스에 htop을 켜봐도 메모리 상태를 보게 되면 안드로이드 스튜디오를 돌리는 것자체로도 2GB씩 차지한다. 하지만 무거운 만한데는 다 이유는 있다. 아래 사진이 안드로이드 OS의 전체적 구조다.





1. Linux Kernel

C,C++언어를 기반으로 이루어져 있으며 리눅스 계열로 이루어진 만큼 보안이 상당히 강력하다. 주로 드라이버로 이루어져 있으며 화면드라이버, 키보드드라이버, 카메라 드라이버 등으로 구성되어져 있다.


2. Library

Linux Kernel과 마찬가지로 C,C++언어를 기반으로 이루어져 있으며, 안드로이드 앱개발에 필요한 중요한 오픈소스 기반의 솔루션들이 다 모여있다. 하지만 취약점이 많아서 보안상에 문제점이 Library쪽에서 많이 발생한다.


3. Android Runtime


구글에서 자체 제작한 Dalvik Virtual Machine, 애플리케이션 제작은 JVM으로 개발한 후에 최종적으로 Dalvik 코드로 변경해서 Target장치에서 구동한다. 안드로이드는 리눅스,라이브러리가 C, C++로 개발되어지고 이루어졌지만 자바로 개발이 가능한 이유가 JVM이라는 자바가상머신이 얹어졌기 때문에 자바로 코딩이 가능하다. 하지만 mySQL, ORACLE과 같은 엔진들은 너무 무겁기때문에 안드로이드에서는 사용하기가 어렵다.


4. Applications Framework


구글에서 JAVA로 자체 제작한 애플리케이션 프레임 페키지다. 주로 활동매니저, 윈도우매니져 등으로 구성되어있다. 말그대로 응용프로그램을 돌리기 위한 프레임워크이다.


5. Applications


이것도 Applications Framework과 마찬가지로 구글에서 JAVA로 자체 제작했다. Application에는 연락처, 전화 브라우저 등등 우리가 주로 일상생활에서 많이 사용하는 휴대폰 앱이 굉장히 많다.







반응형
LIST
블로그 이미지

만년필석사

,
반응형
SMALL

그럼 지난시간에 이어 ADB명령어에는 어떤것들이 있는지 살펴보겠다. 




※ 많이 사용되는 간단한 명령어


1. adb devices - 연결된 디바이스 리스트 보기

<여러개 디바이스 연결시 리스트보는 명령어들>

adb -d logcat (device)

adb -e logcat (emulator)

adb -s emulator-xxx logcat (device serial)


2. adb backup... 디바이스로부터 앱, 데이터 등 백업하는 명령어

3. adb logcat - 디바이스 로그 보기

4. adb -d install 파일명.apk - 디바이스 파일 설치



※ 디바이스에서 많이 사용되는 adb am 명령어들


1. adb kill-server device - 인식이 잘 안될때 케이블을 꼽았다 꼽거나 adb server를 죽인다.

2. adb -d shell - 쉘실행

3. adb -d install -r 파일명.apk - 재설치 

4. adb shell am start -a android.intent.action.MAIN -n com.android.settings/.Settings - 특정액티비티 실행

5. adb shell am start -a android.intent.action.VIEW -d facebook://facebook.com/inbox  - 페이스북 앱실행  

6. adb shell am start -a android.intent.action.VIEW -d file:///sdcard/me.vcard -t text/x-vcard  - sd카드 실행

7. adb shell am start -a android.intent.action.GET_CONTENT -t image/jpeg  -갤러리 실행

8. adb shell am start -a android.media.action.IMAGE_CAPTURE - 카메라 실행

9. adb shell am start -a android.intent.action.MAIN -n com.android.settings/.Settings - 환경설정 실행

10. adb shell am start -a android.intent.action.VIEW http://www.google.com - 구글 실행

11. adb shell am start -a android.intent.action.DIAL tel:010XXXXXXX - 전화번호 다이얼 실행

12. adb shell am start -a android.intent.action.CALL tel:010XXXXXXX - 전화걸기 

13. adb shell am start -a android.intent.action.DAIL -d tel:010-XXXX-XXXX -전화걸기

14. adb shell am start -a android.intent.action.VIEW geo:37.111111-222.333333 - GPS 실행

15. adb shell am start -n com.android.calendar/com.android.calendar.LaunchActivity - 달력실행

16. adb shell am start -a android.intent.action.MAIN -n  패키지명/액티비티 경로 - MainActivity 실행시 사용 
ex) adb shell am start -a android.intent.action.MAIN -n com.example.gunjoolee.stopwatch/com.example.gunjoolee.stopwatch.MainActivity


<출저: http://www.dreamy.pe.kr/zbxe/CodeClip/163972>




이외에도 명령어들을 더 알고 싶으면 이 홈페이지로 가면 더 많은걸 알 수 있다.

http://developer.android.com/tools/help/adb.html





반응형
LIST
블로그 이미지

만년필석사

,
반응형
SMALL

이번시간엔 안드로이드 ADB에 대해서 써본다. ADB란 안드로이드 안에 있는 디버그 툴중 하나이다. 핸드폰에 연결해서 무언가 앱을 실행하고 싶고 디버그 하고 싶을때 리눅스에 명령어만 치면 바로 실행시킬 수 있다. 너무 숨어있는 기능들이 있는데 아마 그런거 찾을때 사용하면 좋지 않나 라는 생각도 해본다. 


1. 터미널 설정



일단 맥북기준으로 설명하겠다. 일단 adb툴이 저장되어 있는 폴더의 경로를 설정해야한다. 경로는 다음과 같다.


export PATH=$PATH:/Users/사용자이름/Library/Android/sdk/platform-tools


안드로이드가 깔리면 파란색으로 표시된 경로쪽에 adb툴이 있다. 그렇기때문에 일단 경로는 저렇게 잡아주고 터미널쪽 환경설정 셸쪽에 다음과 같이 입력한다.




이렇게 경로설정이 완료되면 터미널을 실행하고 adb version을 입력시켜보면 adb가 잘 실행된다는 걸 볼 수 있다. 아래 그림과 같이 실행되면 adb명령어는 잘 실행된다.


2. iterm 설정


iterm에서도 사용하고 싶을때는 경로를 아까 파란색으로 바꿔놨던 경로를 그대로 설정해주면 된다. 조금 더 이해를 돕기위해 다음 아래 그림을 보면 된다.




이런식으로 설정해주고 아까 터미널은 그냥 adb만 입력해주면 명령어가 잘 실행이 되는데 iterm같은 경우는 조금 다르다. 만약 adb 그대로 입력하면 다음과 같은 화면이 나온다.



명령어 실행이 불가능하다고 나온다. 그래서 iterm에서 할때는 다음과 같이 입력을 해야 한다.



adb 앞에 ./을 붙여줘야 실행이 된다는걸 볼 수 있을 것이다. 그럼 하나만 더 예를 들어보면 또 다음과 같다.



지금 방금 친 명령어는 현재 연결되어있는 디바이스 리스트를 나타낸 명령어인데 항상 adb를 실행할땐 ./를 꼭 붙여줘야 한다는걸 알 수 있다. 어떻게보면 터미널에서 사용하는게 더 편할수도 있겠지만 iterm은 툴사용이 자유롭고 배우기도 어렵지 않아 적응만 하면 금방 사용할 수 있을것이다. 어떤걸 사용할 지는 본인이 선택하면 될 것 같다.

반응형
LIST
블로그 이미지

만년필석사

,