Fork me on GitHub
Suzf  Blog

Tag Python

How-to: use Python send mail with To Cc and Bcc

#!/usr/bin/python
# -*- coding:utf-8 -*-

import smtplib
from email.mime.text import MIMEText

to = ['zfsu']
cc = ['zfsu','root']
bcc = ['jack']
from_addr = 'root'
message_subject = "Say Hello"
message_text = "Hello world"
message = "From: %s\r\n" % from_addr \
        + "To: %s\r\n" % ",".join(to) \
        + "CC: %s\r\n" % ",".join(cc) \
        + "BCC: %s\r\n" % ",".join(bcc) \
        + "Subject: %s\r\n" % message_subject \
        + message_text
to_addrs = to + cc + bcc
server = smtplib.SMTP('localhost')
#server.set_debuglevel(1)
server.sendmail(from_addr, to_addrs, message)
server.quit()

 

Use Python send mail

I recommend that you use the standard packages email and smtplib together to send Email. Please look at the following example (reproduced from the Python documentation). Notice that if you follow this approach, the "simple" task is indeed simple, and the more complex tasks (like attaching binary objects or sending plain/HTML multipart messages) are accomplished very rapidly.

Here are a few examples of how to use the email package to read, write, and send simple email messages, as well as more complex MIME messages.

First, let’s see how to create and send a simple text message:

# Import smtplib for the actual sending function
import smtplib

# Import the email modules we'll need
from email.mime.text import MIMEText

# Open a plain text file for reading.  For this example, assume that
# the text file contains only ASCII characters.
fp = open(textfile, 'rb')
# Create a text/plain message
msg = MIMEText(fp.read())
fp.close()

# me == the sender's email address
# you == the recipient's email address
msg['Subject'] = 'The contents of %s' % textfile
msg['From'] = me
msg['To'] = you

# Send the message via our own SMTP server, but don't include the
# envelope header.
s = smtplib.SMTP('localhost')
s.sendmail(me, [you], msg.as_string())
s.quit()

For sending email to multiple destinations, you can also follow the example in the Python documentation:

# Import smtplib for the actual sending function
import smtplib

# Here are the email package modules we'll need
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart

COMMASPACE = ', '

# Create the container (outer) email message.
msg = MIMEMultipart()
msg['Subject'] = 'Our family reunion'
# me == the sender's email address
# family = the list of all recipients' email addresses
msg['From'] = me
msg['To'] = COMMASPACE.join(family)
msg.preamble = 'Our family reunion'

# Assume we know that the image files are all in PNG format
for file in pngfiles:
    # Open the files in binary mode.  Let the MIMEImage class automatically
    # guess the specific image type.
    fp = open(file, 'rb')
    img = MIMEImage(fp.read())
    fp.close()
    msg.attach(img)

# Send the email via our own SMTP server.
s = smtplib.SMTP('localhost')
s.sendmail(me, family, msg.as_string())
s.quit()

As you can see, the header To in the MIMEText object must be a string consisting of email addresses separated by commas. On the other hand, the second argument to the sendmail function must be a list of strings (each string is an email address).

So, if you have three email addresses: [email protected], [email protected], and [email protected], you can do as follows (obvious sections omitted):

to = ["[email protected]", "[email protected]", "[email protected]"]
msg['To'] = ",".join(to)
s.sendmail(me, to, msg.as_string())

the "","".join(to) part makes a single string out of the list, separated by commas.

From your questions I gather that you have not gone through the Python tutorial - it is a MUST if you want to get anywhere in Python - the documentation is mostly excellent for the standard library.

 

Python 执行Linux系统命令的N种方法

前言:
很多时候我们会用到python去调用外部工具/命令去实现某种功能。
I. os
https://docs.python.org/2/library/os.html
os.system
执行流程
system(command) -> exit_status
Execute the command (a string) in a subshell.

# os.system() 是新起一个shell去干活的,对系统的开销比较大
# 仅在一个子终端运行系统命令,而不能获取命令执行后的返回信息
# 无法控制,(如果调用的外部命令,挂死或者执行时间很长),主进程无法控制os.system(), 因为调用os.system(cmd)  调用进程会block, until os.system() 自己退出

In [30]: import os

In [31]: os.system('ls *.py')
check_drive_usage.py  diff_file.py  fcSpider.py  fedspider.py  get_host_list.py  test.py  while.py
Out[31]: 0

os.popen
执行流程
popen(command [, mode='r' [, bufsize]]) -> pipe
Open a pipe to/from a command returning a file object.

# 该方法不但执行命令还返回执行后的信息对象
# 好处在于:将返回的结果赋于一变量,便于程序的处理

In [32]: py = os.popen('ls *py').readlines()

In [33]: print py
['check_drive_usage.py\n', 'diff_file.py\n', 'fcSpider.py\n', 'fedspider.py\n', 'get_host_list.py\n', 'test.py\n', 'while.py\n']

 

II. commands
https://docs.python.org/2/library/commands.html
常用的主要有两个方法:getoutput和getstatusoutput

In [40]: import commands

In [41]: commands.getoutput('ls *.py')
Out[41]: 'check_drive_usage.py\ndiff_file.py\nfcSpider.py\nfedspider.py\nget_host_list.py\ntest.py\nwhile.py'

In [41]: commands.getstatusoutput('ls *py')
Out[41]:
(0,
 'check_drive_usage.py\ndiff_file.py\nfcSpider.py\nfedspider.py\nget_host_list.py\ntest.py\nwhile.py')

 

III. subprocess  [ 推荐使用 ]
https://docs.python.org/2/library/subprocess.html
http://python.usyiyi.cn/python_278/library/subprocess.html
# 运用对线程的控制和监控,将返回的结果赋于一变量,便于程序的处理
# 会自动地加载系统环境变量。
subprocess模块主要用于替代以下几个模块函数
os.system
os.spawn*
os.popen*
popen2.*
commands.*
相对应的subprocess 模块里有 call 函数和 popen 函数 。

1、subprocess.call
call 函数的用法如下:
subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)
可以看出,相对于os模块中的函数,这里可以指定的选项更多。

In [64]: import subprocess

In [65]: subprocess.call('ls *py ',shell=False)
check_drive_usage.py  diff_file.py  fcSpider.py  fedspider.py  get_host_list.py  test.py  while.py
Out[65]: 0

交互式模式下,call 也会有returncode 0 输出,不过在py文件里执行时,ruturn的结果并不会将最后的 0 输出。不过在使用call 函数时,需要注意后面的几个参数:

    开启shell=True是不安全的
    Using shell=True can be a security hazard. See the warning under Frequently Used Arguments for details.
    Note:
    尽量不要启用标准输出和标准错误输出需要管道,call有可能会导致子进程死锁。如需管道时,请使用Popen函数
    Do not use stdout=PIPE or stderr=PIPE with this function as that can deadlock based on the child process output volume. Use Popen with the communicate() method when you need pipes.

subprocess.call 主要用于替换 os.system ,具体如下:

In [66]: subprocess.call('date')
Thu Oct 29 16:02:24 CST 2015
Out[66]: 0

sub.process.Popen的用法如下:

subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)

eg:

In [67]: import subprocess

In [68]: p = subprocess.Popen('ls *.py', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

In [69]: print p.stdout.readlines()
['check_drive_usage.py\n', 'diff_file.py\n', 'fcSpider.py\n', 'fedspider.py\n', 'get_host_list.py\n', 'test.py\n', 'while.py\n']

 

更多内容请移步官网 https://docs.python.org

 

Python 2.6 升级安装 2.7遇到的readline问题

通过上 一篇文章 脚本升级Python到2.7 之后发现一个问题, 在python/iPython交互器(命令行下)不能使用删除/上下键 无语法高亮 ,非常不方便。 检索相关信息,发现pypi有单独的readline模块 pip 安装
^_^[16:29:48][[email protected] ~]#pip install readline
Collecting readline
/usr/local/lib/python2.7/site-packages/pip-7.1.2-py2.7.egg/pip/_vendor/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
  Downloading readline-6.2.4.1.tar.gz (2.3MB)
    100% |████████████████████████████████| 2.3MB 88kB/s
Installing collected packages: readline
  Running setup.py install for readline
Successfully installed readline-6.2.4.1
源码安装
下载地址:https://pypi.python.org/pypi/readline/6.2.4.1
下载后解压安装python setup.py install
最后出错,提示如下
/usr/bin/ld: cannot find -lncurses
collect2: ld returned 1 exit status
error: command 'gcc' failed with exit status 1
原因是未找到ncurses,需要安安装ncurses-devel包后再次安装readline,提示成功,enjoy! FAQ:
    creating build/lib.linux-x86_64-2.7
    gcc -pthread -shared build/temp.linux-x86_64-2.7/Modules/2.x/readline.o readline/libreadline.a readline/libhistory.a -lncurses -o build/lib.linux-x86_64-2.7/readline.so
    gcc: readline/libreadline.a: No such file or directory
    gcc: readline/libhistory.a: No such file or directory
    error: command 'gcc' failed with exit status 1

    readline 是Python的一个内建模块,你看到这些错误信息是因为系统没有完成重建。可能是系统中缺少 patch 包。
    你可以试试 yum install patch
 

Python 版本升级shell简略版

尽管Python3很早之前就出现了但是现在很多企业用的还是2.7居多 天朝系统版本CentOS居多 故以CentOS6为实验环境 Python 从 2.6 升级到 2.7 OoO
#!/bin/bash
# Desc: Python && pip upgrade
# Author: Jeffrey.su
# Mail: [email protected]
# Date:  Oct 09, 2014
# Home: http://suzf.net

DOWN_PATH=/usr/local/src
PY_VERSION=2.7.3
PY_BIN_NAME=python2.7
PY_OLD_VERSION=`python -V 2>&1 | awk '{print $2}'`


function prepare_work(){

  yum -y install zlib  openssl openssl-devel curl wget gcc patch ncurses-devel
  # yum install ipython 

}

function python_upgrade(){

  cd ${DOWN_PATH}
  wget -c https://www.python.org/ftp/python/${PY_VERSION}/Python-${PY_VERSION}.tgz
  tar zxf Python-${PY_VERSION}.tgz
  cd Python-${PY_VERSION}
  ./configure --prefix=/usr/local/Python${PY_VERSION} --enable-shared
  make && make install
  mv /usr/bin/python /usr/bin/python_${PY_OLD_VERSION}
  cp /usr/bin/yum{,.old} && sed -i s/python/python${PY_OLD_VERSION}/ /usr/bin/yum

  ln -s /usr/local/Python${PY_VERSION}/bin/${PY_BIN_NAME} /usr/bin/python

}

function pip_upgrade(){

  cd ${DOWN_PATH}
  curl -O https://pypi.python.org/packages/source/s/setuptools/setuptools-2.0.tar.gz
  tar zxf setuptools-2.0.tar.gz
  cd setuptools-2.0
  python setup.py build && python setup.py install


  cd ${DOWN_PATH}
  curl -O https://pypi.python.org/packages/source/p/pip/pip-7.1.2.tar.gz
  tar zxf pip-7.1.2.tar.gz     
  cd pip-7.1.2    
  python setup.py install
  mv /usr/bin/pip{,.old}  && ln -s /usr/local/Python${PY_VERSION}/bin/pip /usr/bin/pip
  pip install readline
}

 
prepare_work
python_upgrade
pip_upgrade

 

Flask_Faq : AttributeError: 'module' object has no attribute 'autoescape'

前些天从 "spider_net" 上找了一篇文章 , 大致就是利用 highcharts + flask + mysql 构建的一个简单的监控系统 ,
经过几番挣扎终于还是给捣持出来了 , 现在总结一下 , 分享给大家 . o_O

部分报错信息:

* Detected change in 'flask_web.py', reloading
* Restarting with reloader
X.X.X.X - - [11/Jun/2015 15:24:14] "GET / HTTP/1.1" 500 -
Traceback (most recent call last):
...
...
File "/usr/lib64/python2.6/site-packages/jinja2/utils.py", line 195, in import_string
return getattr(__import__(module, None, None, [obj]), obj)
AttributeError: 'module' object has no attribute 'autoescape'

解决办法:
yum install python-pip -y
pip install --upgrade jinja2

redhat 官方宣称这是一个bug , for more :
https://bugzilla.redhat.com/show_bug.cgi?id=799087

Python pip 简单使用说明

简单来说 pip 就是 Python 的一个包管理工具, 和 yum / apt-get 有异曲同工之妙 。
好了, 会到正文
~\(≧▽≦)/~

1、安装
# yum install python-pip -y

or

# wget "https://pypi.python.org/packages/source/p/pip/pip-1.5.4.tar.gz#md5=834b2904f92d46aaa333267fb1c922bb" --no-check-certificate
# tar -xzvf pip-1.5.4.tar.gz
# cd pip-1.5.4 && python setup.py install

# 升级
pip install --upgrade pip


2. 常用操作
# 安装
# pip install pkgname
# python2 -m pip install pkgname
# python3 -m pip install pkgname

# 卸载
# pip uninstall pkgname

# 升级
# pip install --upgrade pkgname

# 检测更新
# pip list --outdated

# 查看
# pip show --files pkgname

# 查看某个库的信息:
# pip show Jinja2

# 查看已经安装的库:
pip list    or   pip freze

3. FAQ :

ImportError No module named setuptools
请参考《ImportError No module named setuptools解决》

4. 参数说明
# pip -h
Usage:
pip [options]

Commands:
install 安装包.
uninstall 卸载包.
freeze 按着一定格式输出已安装包列表
list 列出已安装包.
show 显示包详细信息.
search 搜索包,类似yum里的search.
wheel Build wheels from your requirements.
zip 不推荐. Zip individual packages.
unzip 不推荐. Unzip individual packages.
bundle 不推荐. Create pybundles.
help 当前帮助.

General Options:
-h, --help 显示帮助.
-v, --verbose 更多的输出,最多可以使用3次
-V, --version 现实版本信息然后退出.
-q, --quiet 最少的输出.
--log-file 覆盖的方式记录verbose错误日志,默认文件:/root/.pip/pip.log
--log 不覆盖记录verbose输出的日志.
--proxy Specify a proxy in the form [user:[email protected]]proxy.server:port.
--timeout 连接超时时间 (默认15秒).
--exists-action Default action when a path already exists: (s)witch, (i)gnore, (w)ipe, (b)ackup.
--cert 证书.

Learn more : https://pypi.python.org/pypi/pip

Python 设置终端显示颜色、粗体、下划线等效果

也许你希望在终端上输出一些带有颜色或者粗体、下划线等样式的信息,就像man中的那样,那么这篇文章将会起到些许作用。

在Linux终端中,使用转义序列来进行如上所述的显示,转义序列以ESC开头,即ASCII码下的\033,其格式为:
\033[显示方式;前景色;背景色m
显示方式、前景色、背景色至少一个存在即可。

其中:
显示方式:0(关闭所有效果),1(高亮),4(下划线),5(闪烁),7(反色),8(不可见)。
前景色以3开头,背景色以4开头,具体颜色值有:0(黑色),1(红色),2(绿色),3(黄色),4(蓝色),5(紫色),6(青色),7(白色)。即前景绿色为32,背景蓝色为44。

下面是Python程序编写的输出样式脚本:

#! /usr/bin/python                                                          
# -*- coding: utf-8
 
STYLE = {
        'fore': {
                'black': 30, 'red': 31, 'green': 32, 'yellow': 33,
                'blue': 34, 'purple': 35, 'cyan': 36, 'white': 37,
        },
        'back': {
                'black': 40, 'red': 41, 'green': 42, 'yellow': 43,
                'blue': 44, 'purple': 45, 'cyan': 46, 'white': 47,
        },
        'mode': {
                'bold': 1, 'underline': 4, 'blink': 5, 'invert': 7,
        },
        'default': {
                'end': 0,
        }
}
 
def use_style(string, mode='', fore='', back=''):
    mode = '%s' % STYLE['mode'][mode] if STYLE['mode'].has_key(mode) else ''
    fore = '%s' % STYLE['fore'][fore] if STYLE['fore'].has_key(fore) else ''
    back = '%s' % STYLE['back'][back] if STYLE['back'].has_key(back) else ''
    style = ';'.join([s for s in [mode, fore, back] if s])
    style = '\033[%sm' % style if style else ''
    end = '\033[%sm' % STYLE['default']['end'] if style else ''
    return '%s%s%s' % (style, string, end)
 
def test():
    print use_style('Normal')
    print use_style('Bold', mode='bold')
    print use_style('Underline & red text', mode='underline', fore='red')
    print use_style('Invert & green back', mode='reverse', back='green')
    print use_style('Black text & White back', fore='black', back='white')
 
if __name__ == '__main__':
    test()

其显示效果如下图所示:
Python终端色彩显示展示

转自 Pythoner