본문 바로가기

짜투리

[linux, python] /home 주인님 집에 들어가서 식솔들 집 구경하기

728x90

 

 

 

 

 안녕하세요. 

 

 사실 제목을 어떻게 지어야 할 지 몰라서. 저렇게 지었습니다만. 내용은 다음과 같습니다. 

 다른 후보 제목으로는 "주인님 가솔들 풍비박산내기"가 있었습니다. 

 

 리눅스 /home 하위에 있는 n개의 각 사용자 계정의 특정 루트에 있는 데이터 읽기. 


 

1. 문제상황

 

 /home/main/{생략}/task.py에서 /home 하위에 있는 n개의 각 사용자 폴더의 /data/ttl 폴더의 csv파일만 열어서, 데이터 처리를 한 다음, 처리한 데이터를 다시 저장하는 상황입니다. 

 

/home/main/{생략}/task.py  (현위치)
/home/team1
/home/team2
.
.
/home/team13

 

 

 현위치에서는 permission deny 문제로 /home 하위의 폴더를 읽지 못합니다. 

 

 물론 이때 team 계정의 특정 루트에 폴더가 없거나, csv 파일이 없거나, 원하는 칼럼이 없을 수도 있습니다.

 

 

 그럼 어떻게 하느냐!!! 가 이 게시물의 주제입니다.

 

 당연히 로그인 password를 알고 있어야 하고, 저는 우분투 환경에서 작업했습니다.


2. python에서 /home 하위 폴더 접근

 

 일단 제 python 코드는 아래와 같습니다.  

 

 데이터를 처리할 코드는 Address_mapping.py에 클래스로 정의해서 사용했고. 

 

  if문 조합+log문을 통해서 문제가 발생한 원인과 계정 정보를 파일에 작성했습니다. 

 

import os, re
import pandas as pd
from tqdm import tqdm
import datetime
from Address_mapping import Mapping

# 로그 작성 ------------------------------------------------------------------
def log(log_message, log_file_path="./data/result/log.txt"):
    current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    log = f"{current_time}: {log_message}"
    
    if not os.path.exists(log_file_path):
        with open(log_file_path, 'w') as log_file:
            log_file.write(log + "\n")
    else:
        with open(log_file_path, "a") as log_file:
            log_file.write(log + "\n")

# 메인 -----------------------------------------------------------------------------------
if __name__ == "__main__":
    # 매핑 클래스 정의
    log("매핑 클래스 정의\n")
    mapping = Mapping()
    
    # 팀 폴더 확인 
    user_path = "/home"; csv_data_path = "data/ttl"
    user_name_list = [username for username in os.listdir(user_path) if username.startswith('team')]

    # 매핑
    for username in tqdm(user_name_list):
        log(f"{username}: 데이터 매핑 시작")
        team_path = os.path.join(user_path, username)
        target_folder_path = os.path.join(team_path, csv_data_path)

        if os.path.exists(target_folder_path):
            target_file_list = [filename for filename in os.listdir(target_folder_path) if filename.endswith('.csv')] 

            if len(target_file_list)!=0:
                for filename in target_file_list: 
                    file_path = os.path.join(target_folder_path, filename)
                    df = read_csv(file_path)
                    result = mapping.run(df)

                    if type(result)==str:
                        log(f"{username}: {file_path} 타켓 칼럼 없음\n")
                    else:
                        new_filename = f'{filename.split(".csv")[0]}_addr.csv'
                        result.to_csv(os.path.join(target_folder_path, new_filename))
            else:
                log(f"{username}: {target_folder_path} 경로에 csv파일 없음\n")
        else:
            log(f"{username}: {target_folder_path} 폴더 없음\n")

 

 

  이제 터미널을 열고. 아래 명령어를 사용하면 됩니다. 

 

sudo su  # 다른 계정 정보 확인 및 접근
python task.py

 

 

 만약에 가상 환경을 써야 한다면 아래 명령어를 사용하면 됩니다.

 

sudo /home/main/miniconda3/envs/{아나콘다 가상환경 이름}/bin/python3 task.py
# sudo에서는 python이 안 되므로, 콘다 환경을 써야할 때 환경 위치를 명시해줘야 함
# 이렇게 안 하면 /home/team 권한이 없어서 코드를 돌릴 수가 없음

 


 

 요약하자면 sudo su를 쓰세요. 

 

 저는 가상환경에서 애를 먹었는데. 이렇게 쓰면 된답니다.