rand(life)

[vba] 리눅스에 접근하여 명령내리기 본문

컴퓨터/엑셀

[vba] 리눅스에 접근하여 명령내리기

flogsta 2022. 5. 3. 18:19

NAS서버에 파일을 올려놓고

VBA로 특정 검색어를 가진 파일이나 폴더명을 가져오는 일이 많다.

FileSystemObject를 이용했지만

파일이나 폴더가 많아지다보니

그때마다 하위 디렉토

리까지 모두 긁어서 가져오려면 시간이 한참 걸린다

그래서 생각한 방법은

리눅스에서 ls > list.txt 명령은 빠른 시간에 해당 폴더 내의 목록을 list.txt 라는 파일로 저장할 수 있으므로

원하는 폴더에 list.txt 파일을 만들어두고

검색을 하고 싶으면 list.txt 파일을 열어서 찾으면 더 시간이 적게 걸릴 수 있겠다는 생각으로 검색해보았고

몇번의 삽질 끝에 완성했다

Option Explicit

 Sub com_make_listFile()
    Dim a, i&
    Dim console As Object
    Dim shell As Object
   ' /var/services/homes/kkkk/ 경로 밑에 있는 folder1,folder2,folder3의 폴더에 list.txt 파일을 만든다고 가정
    Const sPath As String = "/var/services/homes/kkkk/"
    a = Split("folder1,folder2,folder3", ",")

    Set shell = CreateObject("WScript.Shell")

    '111.222.33.44 서버에 9999포트로 접속하고, 접속 아이디는 jjjj, 비밀번호는 1234 라고 가정한다
    'plink 프로그램을 사용한다. putty를 다운로드하면 그 안에 들어있다
    Set console = shell.Exec("C:\Program Files\PuTTY\plink -ssh -pw 1234 -P 9999 jjjj@111.222.33.44")

    'WaitForResponseText는 나스에 접속했을때 모니터에 출력해주는 메시지의 끝단어를 기다린다.
    '즉, 다음 동작을 하기 전에 나스가 명령을 받아들일 준비가 되어있는지를 확인하기 위함이다
    '우리집 나스는 로그인했을때 출력하는 메시지의 마지막 어구가 at your own risk.이다
    WaitForResponseText console, "at your own risk."

    '위에서 설정한 폴더 각각에 대해 실행한다.
    For i = LBound(a) To UBound(a)
    'cd : 해당 폴더로 이동
     console.StdIn.Write ("cd " & sPath & a(i) & vbCr)
     'cd 명령이나 ls 명령은 수행하고 나면 딱히 다른 메시지를 출력하지 않으므로,
     'WaitForResponseText 뒤에 두번째 인수는 공백 ""이다
     WaitForResponseText console, ""
     'ls 목록을 출력하여 list.txt 파일로 저장한다
     console.StdIn.Write ("ls > list.txt" & vbCr)
     WaitForResponseText console, ""
    Next '다음 폴더로 넘어감

    '모든 폴더에 대해 작업이 끝났으면 종료 명령 exit
    console.StdIn.Write ("exit" & vbCr)
    WaitForResponseText console, ""
   MsgBox "Done"
 End Sub

 Sub com_WaitForResponseText(console As Object, response As String)
    Dim out As String

    '출력메시지가 없으면 종료
    If console.StdOut.AtEndOfStream Then Exit Sub

    Do
    '출력메시지를 받아들인다
        out = console.StdOut.ReadLine()
        'DoEvents는 없어도 되지만 혹시 에러나면 plink창을 끔으로써 작업을 종료시킬 수 있다
        DoEvents
        '출력메시지를 직접실행창에 보여준다. 에러 확인을 위해.
        Debug.Print out
        '설정된 마지막 메시지가 들어있는지 확인
        If InStr(out, response) Then
            Exit Do '있으면 종료
        End If
        out = "" ' 변수 초기화
    Loop Until console.StdOut.AtEndOfStream '마지막 메시지까지 실행
End Sub

코드출처:

https://stackoverflow.com/questions/20796017/call-a-unix-script-from-excel-vba