2016-10-10 3 views
-1

저는 사용자 데이터를 캡처하고 사용자 데이터에서 일부 cgi를 실행하는 양식을 가진 웹 사이트를 만들고 있습니다. cgi의 첫 번째 단계 중 하나는 Linux 웹 서버에서 Windows 시스템으로 파일을 복사해야한다는 것입니다. 서버는 복사 자격 증명에 활성 디렉토리 역할 acount를 사용합니다. 나는 단순히 같은 것을 사용하기를 희망했다 :파이썬은 리눅스에서 WIndows로 파일을 복사합니다.

mount -t cifs -o username=someUsername,password=somePasword //someMachine/someShare /someMountPoint 

불행하게도 내가 bash는 그 명령을 실행할 때 암호에 대한 오류가 무효 인 때문 얻을. 이상적으로이 방법을 사용하여 원격 Windows $ share를 마운트 한 다음 파일을 복사하지만 더 합리적인 경우 다른 모듈을 사용해 볼 의향이 있습니다.

나는 이와 같은 것을 가지고 있지만 작동하지 않으며 필요한 임시 디렉토리를 생성하지만 결코 아무것도 마운트하지 않습니다. 나는 다른 것을 사용하게되어서 기쁘지만 무엇이 잘못되었는지 알고 싶어합니다.

import subprocess 
import random 


def makeDir(): 
    tempDir = random.randrange(111111,999999) 
    subprocess.Popen(["mkdir","/mntDir/"+str(tempDir)]) 
    return tempDir 

def mountShare(hostname, username, password): 
    mountDir = makeDir() 
    try: 
     subprocess.Popen(["mount","-t","cifs", "-o", 
         "username="+username+",password="+password, 
         "//"+hostname+"/c$", 
         "/mntDir/"+mountDir]) 
    except: 
     print("Mounting failed") 

+0

평상시의 일상적인 작업을 위해 Windows 서버 (C $ 공유에 필요)에 대한 관리자 권한이 있고 Linux 서버에 파일 시스템을 마운트하는 루트 권한을 가진 웹 사이트를 실행 하시겠습니까? Eww. Windows 서버의 제한된 사용자 계정을 올바른 폴더 및 공유 사용 권한으로 사용하는 것이 훨씬 낫고, Linux 사이드의 [smbclient] (http://superuser.com/a/562728)와 같은 것을 마운트하지 않아도됩니다. 전혀 공유하지 마라. (random, random bodge를 피하기 위해 [tempfile] (https://docs.python.org/3/library/tempfile.html) 모듈을 확인하십시오. – TessellatingHeckler

+0

예, 계정에 관해서는 동의하며 피해야합니다. 이 사이트는 소규모 그룹으로 제한되며 내부적이지만 보안은 분명 중요합니다. 원격 컴퓨터에서 공유를 실제로 사용할 수는 없지만 사용자가 즉시 자격 증명을 제공 할 수는 있습니다. 입력 주셔서 감사합니다, 나는 확실히 smbclient를 사용하는 가능성을 살펴보고, 나는 또한 tempfile 모듈의 모양을 좋아한다. 감사합니다 –

답변

0

pysmb (https://pythonhosted.org/pysmb/api/smb_SMBConnection.html)에있는 SMBConnection 클래스를 사용했습니다. 설치가 매우 간단하고 필요가 없습니다.

conn = SMBConnection(user, pw, myname, srv, use_ntlm_v2 = True) 
conn.connect(ip, port=139) 
file2transfer = open(filename,"r") 
conn.storeFile(share,path + filename, file2transfer, timeout=30) 

사용자에게 파일 공유에 대한 로그온 권한이 있는지 확인하십시오.

+0

이것은 완벽한 솔루션입니다. 나는 다른 코드를 제거하고 이것으로 대체했다. 나는 그것을 훨씬 더 신뢰성 있고 빠르다는 것을 알게되었다. 감사합니다. –

0

이 방법은 두 가지 단점이 있습니다 : 첫 번째는 당신이 당신의 웹 서버에서 윈도우 공유를 마운트 점이다. 동적으로 마운트 할 필요가 없으며 모든 요청에 ​​대해 마운트하지 않아야합니다. 구현과 인프라를 분리하십시오./etc/fstab에 필요한 디렉토리를 마운트하고 웹 서버가 디렉토리의 존재에 의존하게하십시오.

하지만 또 다른 문제가 있습니다. 파일을 다른 컴퓨터로 복사하는 이유는 무엇입니까? 거기에서 처리하고 싶습니까? Windows 머신에 데이터를 처리해야한다는 것을 어떻게 알리고 싶습니까? 다른 웹 서버를 실행하여 처리해야하는 경우 요청을 보내지 않는 것이 좋습니다. 그리고이 시점에서 모든 네트워크 파일 시스템을 삭제하고 요청 내에서 파일을 보낼 수 있습니다. 그래서 리눅스 기반 프론트 엔드 서버는 윈도우 백엔드 서버에 HTTP 요청을 보내서 몇 가지 작업을 수행합니다. 이렇게하면 처리가 준비되면 프론트 엔드에 알릴 수 있습니다. 어쨌든, Popen을 오류 정보를 숨기고 그들이 (찾을 수 없음으로 인해 명령) 명령을 시작할 수 없을 때 다른 subprocess 방법은 예외를 던질로

+0

고마워요, 무슨 뜻인지 알 겠어요. 기본적인 생각을 이해한다고 생각합니다. linux apache 서버는 https를 사용하는 양식을 실행하며 사용자 로그온이 필요합니다. 양식에 의해 수집 된 데이터는 사용자 이름, 다른 간단한 변수 및 원격 Windows 데스크탑 시스템 호스트 이름입니다. 이 데이터는 원격 데스크톱 컴퓨터뿐만 아니라 추가 소프트웨어 구성 요소에 복사되는 응답 파일을 만드는 데 사용됩니다.이 소프트웨어 구성 요소는 내가 책임지지 않습니다. 그런 다음 원격 컴퓨터에서 exe를 트리거해야합니다. 모든 과정 중에 삭제됩니다. –

0

첫째, mount가 실제로 호출 즉, 예외 블록을 놓습니다.

둘째, 귀하의 경우에는

rc = subprocess.call(["mount","-t","cifs", "-o", 
         "username="+username+",password="+password, 
         "//"+hostname+"/c$", 
         "/mntDir/"+mountDir]) 
if rc: 
    print("mount failed") 

을 당신이 정말로 Popen하지만 call 필요하지 않습니다 (그리고 보너스로 직접 리턴 코드를 얻을 수), 문제 일반 예외 블록이다.

이 방법 당신은 당신이 정수 (TypeError: Can't convert 'int' object to str implicitly)로 문자열을 추가하는 때문에 오류가 예외 블록을 제거 그래서 만약

def makeDir(): 
    tempDir = random.randrange(111111,999999) 
    subprocess.Popen(["mkdir","/mntDir/"+str(tempDir)]) 
    return tempDir 

는, 정수를 반환합니다. 그것은 당신을 오도하는 어리석은 예외 잡기가 아니라면 당신이 볼 수있는 간단한 실수입니다.

그러나 인수없이 일반 try/except 블록을 사용하면 mount failed 쓸모없는 메시지 만 표시됩니다. 결코은 진술을 try:/except:으로 보호하십시오. 역효과가 있습니다.당신이 정말 그렇게하려면

, 이렇게 :

:

이제
try: 
    some_command 
except Exception as e: 
    # print detailed exception, not just "error" 
    print("Something went wrong "+str(e)) 

그것을 요약하면, 여기에 (보너스로 약간의 개선) 코드의 고정 된 버전입니다

import subprocess,os 
import random 


def makeDir(): 
    # directly create directory name as a string 
    tempDir = "/mntDir/{}".format(random.randrange(111111,999999)) 
    # no need for a subprocess, python handles this well! 
    os.mkdir(tempDir) 
    # returns the absolute directory name, as string 
    return tempDir 

def mountShare(hostname, username, password): 
    mountDir = makeDir() 
    rc = subprocess.call(["mount","-t","cifs", "-o", 
         "username="+username+",password="+password, 
         "//"+hostname+"/c$", 
         mountDir]) 
    if rc!=0: 
     print("Mounting failed") 
+0

수정 해 주셔서 감사합니다. 당신이 말하는 것은 좋은 조언을 해주셔서 감사합니다. –

0

해결책은 공유를 마운트하는 것이 아니라 smbclient를 사용하여 즉시 복사하는 것입니다. 다음에 사용되는이 파일에

username = yourUsername 
password = yourPassword 
domain = yourDomain 

권한이 500

smbclient를 명령으로 설정 : 내가 사용 명령의 형식의 관련 권한을 가진 계정을 포함하는 authfile을 말한다 원격 시스템에 디렉토리를 작성하고 해당 디렉토리에 파일을 복사하십시오.

smbclient //hostname/c$ -A /authfile -c "mkdir someDir; cd someDir/; lcd /folderToCopyFrom; prompt; recurse; mput *; exit;" 

조언 해 주셔서 감사합니다.

관련 문제