Upload
satoshi-yamada
View
804
Download
10
Embed Size (px)
Citation preview
#STAPYでLTを6回やらせていただきました
http://www.slideshare.net/satoshiyamada71697
stapy05-stapy11Pythonでハガキに宛名書きする方法PythonでIPMessenger送る方法15分で情シスに怒られる方法etc
実際シェルスクリプトが多いシェルスクリプトで凝ったことするの辛い…Python書き慣れてるし…こっちがいいLinuxならPython最初から入ってるし(新しいリリースとはいっていない)Windowsに移植できる(やったとはいっていない)
LS でファイルのリストがほしいls -lR *.py的なことがしたい
os.walkで全部拾ってglobでマッチング
def ls(start_dir, match_rule="*"): """ 指定した条件を満たすファイル一覧を取得する :param start_dir:捜索開始位置 :param match_rule: globに渡すファイル名のマッチングルール :return: dir_list, file_list """ file_list = [] for dirpath, dirnames, filenames in os.walk(start_dir): for filename in filenames: tmp_file_name = os.path.join(dirpath, filename) # ファイル名がルールを満たすか if glob.fnmatch.fnmatch(filename, match_rule): file_list.append(tmp_file_name)
return file_list
OSコマンドを叩きたいsubProcessで出来るcommunicate()で、がっと実行して結果を取る
def exec_os_command(command_str): """ OSコマンドを実行する。コマンドはshell上で実行される
:param command_str:実行するコマンド。オプションなども文字列で渡す :return: """ # 現在の環境変数をコピーしておく child_env = os.environ.copy() # LANG=Cが安定 child_env["LANG"] = "C" p = subprocess.Popen( command_str,stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.PIPE,env=child_env, shell=True ) # EOF を送りつける stdout, stderr = p.communicate() return stdout, stderr
ある文字列ふくまれてるかチェックしたい
re(り?れ?)でOK
In [7]: stdout, stderr = exec_os_command("ls l /")In [9]: bin_pattern = re.compile(r"bin")In [10]: for line in stdout.split("\n"): ....: if bin_pattern.search(line): ....: print line ....: drwxrxrx 2 root root 4096 Mar 8 09:51 bindrwxrxrx 2 root root 12288 Mar 29 08:35 sbin
時刻処理全般datetimeただし、2.4ではstrptime/strftimeがないので注意
def to_date(date_string, date_format): """ 日付文字列をdatetime.datetimeオブジェクトにして戻す :param date_string: 処理対象の文字列 :param date_format: 日付フォーマット :return: """ # 2.4でstrptimeがないためのハック if hasattr(datetime, 'strptime'): # python 2.6 strptime = datetime.strptime else: # python 2.4 equivalent strptime = lambda date_string, format: datetime.datetime(*( \ time.strptime(date_string, format)[
return strptime(date_string, date_format)
In [15]: to_date("20160102 13:45", "%Y%m%d %H:%M")Out[15]: datetime.datetime(2016, 1, 2, 13, 45)
XMLとかHTMLとか解釈したいxmlモジュールつらいBeautfulSoup使いたいBeautifulSoup4は色々依存してる(lxml,html5lib)BeautifulSoup3なら単一ファイル置くだけ!(多分BadKnowHow...)
In [1]: from BeautifulSoup import BeautifulSoupIn [2]: import urllib2In [3]: response = urllib2.urlopen('https://github.com/denzow/ipymessenger')In [4]: html = response.read()In [5]: soup = BeautifulSoup(html)In [7]: soup.title.stringOut[7]: u'GitHub denzow/ipymessenger: IP messenger via python library'In [16]: link_list = soup.findAll("a")In [17]: link_list[1].get("href")Out[17]: u'https://github.com/'
SUDOしたいroot実行のスクリプトから特定ユーザにsudoしてコマンド叩きたいuid,gidを特定してos.setuid/os.setgidすればOK!def check_uid_and_gid(user_name): """ ユーザのuidとgidを取得する :param user_name: ユーザ名 :return: uid, gid """ # passwdを開いて確認スル etc_passwd_file = open("/etc/passwd") etc_passwd = etc_passwd_file.readlines() etc_passwd_file.close() attrs = [ None for x in range(4)] for line in etc_passwd: if line.find(user_name+":") == 0: # v1124:x:501:502::/home/v1124:/bin/bash attrs = line.split(":") break return int(attrs[2]), int(attrs[3])
class SudoSetUp(object): """ Subprocessに渡してsudoさせるためのクラス """ def __init__(self, uid, gid): self.uid = uid self.gid = gid
def sudo(self): # 指定されたIDですでに起動しているなら何もしない if self.uid == os.getuid() and self.gid == os.getgid(): pass else: os.setgid(self.gid) os.setuid(self.uid)
あとはsubprocess.Popenのpreexec_fnに引き渡すだけで、fork時にuid/gidを書き換えて実行してくれる
def exec_os_command(command_str, user_name, return_code_check=True): """ OSコマンドを実行する。コマンドはshell上で実行される: :return: """ # 現在の環境変数をコピーしておく child_env = os.environ.copy() # LANG=Cが安定 child_env["LANG"] = "C" # passwdからuid/gidの取得 uid, gid = check_uid_and_gid(user_name) sudoset = SudoSetUp(uid, gid)
p = subprocess.Popen( command_str,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE, preexec_fn=sudoset.sudo, # ここ! env=child_env, shell=True )