Linux基础
知识点: 用户权限 链接 数据重定向 文本处理:vim awk sed 正则表达式 软件包管理:rpm yum 源码编译
修改CentOS7网卡名称为eth0 :
gedit /boot/grub2/grub.cfg linux16 后加 net.ifname=0
sed -i.bak ‘s/rhgb quiet/rhgb quiet net.ifname=eth0/’ /etc/default/grub
ntp时间同步 : ntpdate $NTP_SERVER
gedit /etc/ntp.cfg
server $NTP_SERVER ibrust
service ntpd start
screen屏幕同步操作: 连接同一台主机 一台使用screen -S help命令 创建名为help的会话连接 另一台使用screen -x help 加入help会话 双方都可修改 都可输入exit退出会话
双引号可识别变量,不可识别命令
单引号命令与变量均不识别
命令调用命令 用$() 或 “(反引号) 命令与变量均可识别
touch /data/file{1,2,3}.{txt,log}
date +%F 生成日期,年月日格式2018-03-11
history 查看历史命令 !数字 : 执行历史记录中对应数字的命令 !:0 执行上一条命令 不带参数 !$上一条命令的最后一个参(按Esc后按.键 或者同时按Alt和.键) !英文字母 : 执行历史记录中最近以英文字母开头的命令 历史命令个数由$HISTSIZE变量决定 位于/etc/profile文件的HISTSIZE行
Ctrl+r 搜索历史命令
如何查看命令帮助:
内部命令(加载在内核) help CM / man bash 外部命令 (在各个bin目录) CMD –help 内部/外部命令查看 type which
rm别名为mv: nano ~/.bashrc alias rm=’mv -t /backups’
硬链接VS软链接
硬连接 软链接
- 根本区别 一个文件,多个名字 多个不同文件
- 跨分区 不可跨分区 可以跨分区
- inode 同 异
- 链接数 异 同
- 链接目录 不可 可以
- 删除 不影响源文件 影响
重定向
Linux给程序提供三种I/O设备
STDIN – 0 标准输入
STDOUT – 1 标准输出
STDERR – 2 标准错误
STDIN STDOUT 重定向至文件:
STDOUT重定向 2>STDERR重定向 &>所有输出重定向
ls &> /data/all.log
ls > /data/all.log 2>&1 >只保留本次输入的内容 上次的内容覆盖掉
ls >> /data/ls.out >>为追加保存 不会覆盖以前的数据
set -C 禁止覆盖 可追加 STDOUT STDERR都写入文件
/etc/passwd文件描述
由:分割为7个字段(列)
第一列 用户名
第二列 X 早期的系统存放加密的登录口令 (现已失效,密码存放于/etc/shadow中.为兼容旧版本此项保留)
第三列 UID
第四列 GID
第五列 用户信息
第六列 所属组
第七列 SHELL类型
管理用户与组
linux系统内三类用户 : 文件的所有者 所属组 其他人 .分别用 U G O 表示
而每类人对文件又有读写和执行三类权限.分别用RWX表示
权限位 |
文件 |
目录 |
r |
可以读文件 |
可以查看目录中内容 |
w |
可以写文件 |
可以增删目录中内容 |
x |
可以执行文件 |
可以进入目录 |
创建 useradd groupadd
修改 usermod groupmod
删除 userdel groupdel
密码 passwd gpasswd
切换用户 su &USERNAME 非登录式切换,不读取目标用户配置文件
su – &USERNAME 登陆式切换,读取目标用户配置文件
提权 sudo 普通用户以目标用户(默认为root)的身份执行命令而不需要输入目标用户密码.
配置文件 /etc/sudoers root用户只读.可用visudo命令修改,有语法检测
visudo编辑规则 :帐号 来源主机名 = (可切换的身份) 可通过sudo执行的命令
6k ALL=(root) /usr/bin/passwd #6k用户可从任意来源的主机已root身份执行passwd命令
创建名为mysql的系统帐号 指定相同的UID和GID
groupadd -g 666 mysql
#-g 666 指明GID为666
useradd -u 666 -r -s /sbin/nologin -g mysql mysql
#-u 666 指明UID为666 -r 创建系统用户 -s /sbin/nologin 指定SHELL为nologin -g mysql 指定用户为mysql组
创建名为gentoo的一般用户,附加组为distro和linux,默认shell为/bin/csh,注释信息为”GentooDistribution”
groupadd distro,linux
useradd -G distro,linux -s /bin/csh -c “GentooDistribution” gentoo
r=4 w=2 x=1
rwx = 二进制的111 = 十进制的7
rw- = (110)B = (6)D
— = 0 = 0
umask
用来规定新建文件与目录的默认权限 在/etc/profile文件中设置可对所有用户生效
umask的后三位+默认权限值 =666(file) | 777(dir)
但新建文件均无执行权限
只有一种情况. 对文件,用666减umask结果如果有奇数,加1.
umask默认值为0 0 2 — — -w-
目录权限 rwx rwx r-x (775) 目录创建的默认权限
文件权限 rw- rw- r– (664) 文件创建的默认权限
SUID 4 继承用户所有者的权限
SGID 2 继承用户所属组的权限
STICKY 1 除了文件所有者和root 其他人即使对目录有鞋权限也无法修改或删除文件
可执行文件SUID权限:
ll /etc/passwd
-r-s–x–x 1 root root 21944 Feb 12 2006 /usr/bin/passwd
1.SUID的作用仅针对于二进制程序。
2.使用者要对该二进制程序有”x”权限
3.”以文件拥有者的身份”只在执行过程中有效(执行过程中我获得了该程序owner的权限)
例子就好比 /usr/bin/passwd 这个二进制文件。
它的权限是 -rwsr-xr-x ,我不是所有者,我具有”x”权限,我执行它时,获得了它的所有者(即root)的权限,所以在该二进制程序执行时,我可以用它来读到我平时是没有权限访问的 /etc/shadow 文件(-r——–),从而能更改我自己的密码。
目录STICKY权限:
无论一个文件的权限或拥有者如何.只要对该目录具有写权限,普通用户可以删除该目录中的任何文件,包括其他普通用户和root的的文件.
在目录设置Sticky 位,只有文件的所有者或root可以删除该文件.但设置在文件上无意义./tmp目录默认为rwxrwxrwt权限
STICKY权限设定:
chmod o+t DIR…
chmod o-t DIR…
chmod[124]755
124分别为sticky SGID SUID
例如:
ls -ld /tmp drwxrwxrwt 12 root root 4096 Nov 2 15:44 /tmp
可执行文件上SGID权限
任何一个可执行程序文件能不能启动为进程:取决发起者对程序文件是否拥有
执行权限
启动为进程之后,其进程的属组为原程序文件的属组
权限设定:
chmod g+s FILE…
chmod g-s FILE…
目录上的SGID权限
默认情况下,用户创建文件时,所属组为此用户所属的主组
一旦某目录被设定了SGID,则对此目录有写权限的用户在此目录中创建的文件的所属组为此目录的属组
通常用于创建一个协作目录
权限设定:
chmod g+s DIR…
chmod g-s DIR…
查看文本的命令
cat tac rev more less
head
tail 看文本的后几行 常用于跟踪日志
tail -f 跟随模式,显示文本内容的变化
cut -d: #指定:为分割符 -f1,3-5 #取第一以及第三至第五列
cut -d: -f1,3-5 /etc/passwd
df -h | cut -c34-36 #取第34至36列
取IP地址
ifconfig |head -2 |tail -1 |cut -c21-36 #head -2 #取前两行 tail -1 #取后一行 cut -c21-36#取第21至第36列
centos6
ifconfig |head -2 |tail -1 |cut -d: -f2 |cut -d’ ‘ -f1
ifconfig |head -2 |tail -1 |tr -s ” “| cut -d’ ‘ -f3 | cut -d: -f2 #tr -s ” “压缩空格
centos7
ifconfig |head -2 |tail -1 |cut -d’t’ -f2 |cut -d’ ‘ -f2
取分区利用率
df |tr -s ” ” “%”|cut -d% -f5 #tr -s ” ” “%” 将空格替换为%
合并文件
paste 左右合并
cat 上下合并
统计访问网站的前十名用户
cut -d” ” -f1 access_log|uniq -c|sort -nr|head -10
cut -d” ” -f1 access_log #以空格为分隔符,取第一列
uniq -c #统计频次(第一列为频次 第二列为文本数据)
sort -nr #以数值大小降序排列 sort默认对第一列排序
head -10 #取前10行
uniq -d #求同
uniq -u #存异
分类 sort -t “:” -k3 /etc/passwd
去重 uniq -d
输出1到55之间的随机数 echo $[RANDOM%55+1]
正则表达式取IP地址
ifconfig eth0 | grep “[[:digit:]]\{1,3\}\.[[:digit:]]\{1,3\}\.[[:digit:]]\{1,3\}\.[[:digit:]]\{1,3\}”
ifconfig eth0 | grep addr |grep -o “[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}”
ifconfig eth0 | grep addr |grep -o “\([0-9]\{1,3\}\)\.\1\.\1\.\1”
ifconfig eth0 | grep addr |grep -o “\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}”
ifconfig eth0 | grep addr |grep -Ewo “([0-9]{1,3}\.){3}[0-9]{1,3}”
cut取列 cut -d: -f1,3-5 /etc/passwd #可灵活运用冒号 空格 百分号甚至某个单词作分隔符取列
sort排序 sort -t “:” -k3 /etc/passwd
uniq统计频次 uniq -c 第一列为频次 第二列为文本
uniq -d #求同
uniq -u #存异
tr -s ” ” #压缩空格
tr -s ” ” “%” #将空格替换为%
取IP地址
centos6
ifconfig |head -2 |tail -1 |cut -d: -f2 |cut -d’ ‘ -f1
ifconfig |head -2 |tail -1 |tr -s ” “| cut -d’ ‘ -f3 | cut -d: -f2 #tr -s ” “压缩空格
ifconfig eth0 | grep -Eow “([0-9]{1,3}\.){3}[0-9]{1,3}”
centos7
ifconfig |head -2 |tail -1 |cut -d’t’ -f2 |cut -d’ ‘ -f2
取分区利用率
df | tr -s ” ” “%”|cut -d% -f5 #tr -s ” ” “%” 将空格替换为
统计访问网站的前十名用户
cut -d” ” -f1 access_log|sort|uniq -c|sort -nr|head -10 以空格为分隔符 截取第一个字段 再排序统计
sort -t ” ” -k 1 access_log |cut -d ” ” -f1 |uniq -c |sort -nr |head -n 10 先对第一列排序 再排序统计
统计安装光盘Packages目录下各平台的安装包数量
ls *.rpm |rev |cut -d. -f2|rev |sort |uniq -c #rev命令将 文件名逆序打印,逆序后可用.作分隔符取出第二列 再次逆序打印 最后排序统计
ls *.rpm | grep -Eo “\.\<[[:alnum:]_]+\>\.rpm$” |cut -d. -f2 |sort |uniq -c #[[:alnum:]_]+表示字母 数字 下划线至少出现一次 左右加\<>\表示匹配整个单词 最后左右再加..rpm可取出两个点中间的单词
ls *.rpm | grep -Eo “\.[^.]+\.rpm$” |cut -d. -f2|sort |uniq -c 取出..rpm两点中间不是.的单词
正则表达式
grep -i忽略大小写 -v不显示匹配到的行(取反) -o 只显示匹配到的字符串 -E 扩展正则表达式
字符匹配
. 任意单个字符
[] 范围内多选一
[^] 范围外多选一
次数匹配
.* 任意长度 任意字符
*任意多次 可为0次
\?0或1次
\+至少1次
\{n,m\} 匹配前面的字符至少n次,至多m次
位置锚定
^行首
$行尾
^PATTERN$ 匹配整行
^$ 空行
\<词首
\>词尾
\b词首或词尾
\<PATTERN\>匹配单词
分组
将一个或多个字符绑在一起,当作整体处理 用\(\)括起来
后向引用 : \(\)中的内容可用 \1 \2 \3 代替 此时\[123]表示已经匹配到的字符 而非模式本身 即两者内容一致
扩展正则表达式次数匹配和分组可去除反斜线,不用转义
vim 是vi的增强版 是交互式文本编辑器
一共有三个模式
1 编辑模式/命令模式 刚打开文件进入的模式
2 输入模式
3 末行模式
编辑模式
按ESC键 可从任意模式切换至编辑模式
进入输入模式
i 光标前方 I 行首
a 光标后方 A 行尾
o 光标下一行 O 光标上一行
总结:小写iao分别表示光标前后以及下一行 大写字母表示移至行的首位或上一行
移动光标
单次移动 方向键或者hjkl
单词间移动 w下一单词词首 e当前单词或下一单词词尾 b当前单词或下一单词词首
行内移动 ^行首的首个非空字符 0绝对行首 $绝对行尾
句子间移动 ()
段落间移动 {}
编辑模式 输入:wq! 强制保存退出 快捷键ZZ(不推荐)
sed 非交互式行编辑器,适合批量编辑大量文本文件,简化多次操作过程.
每次从文本读一行,存于模式空间(pattern space)中.处理后送至标准输出,再处理下一行…
sed [option]… ‘script’ inputfile…
常用选项:
-n:不输出模式空间内容到屏幕,即不自动打印
-i.bak: 备份文件并原处编辑
script:’地址命令’
地址定界:
(1) 不给地址:对全文进行处理
(2) 单地址:#: 指定的行,$:最后一行
/pattern/:被此处模式所能够匹配到的每一行
(3) 地址范围:
#,# 第#行到第#行
#,+# 第#行往后加#行
/pat1/,/pat2/ pat1到pat2之间的行
#,/pat1/第#行 到pat1之间的行
(4) ~:步进
1~2 奇数行 从第1行开始依次往后加两行
2~2 偶数行 从第2行开始依次往后加两行
编辑命令:
d: 删除模式空间匹配的行,并立即启用下一轮循环
p:打印当前模式空间内容,追加到默认输出之后
a [\]text:在指定行后面追加文本
支持使用\n实现多行追加
i [\]text:在行前面插入文本
c [\]text:替换行为单行或多行文本
w /path/somefile: 保存模式匹配的行至指定文件
r /path/somefile:读取指定文件的文本至模式空间中匹配到的行后
=: 为模式空间中的行打印行号
!:模式空间中匹配行取反处理
替换标记:
g: 行内全局替换
p: 显示替换成功的行
w /PATH/TO/SOMEFILE :将替换成功的行保存至文件中
ifconfig |sed -n ‘2p’#只打印第二行结果
seq 10 |sed -n ‘2~2p’ #只打印偶数行
seq 10 |sed -n ‘$p’ #只打最后一行
sed -n /^#/p /etc/fstab #只打印以#开头的行
sed -n /^[^#]/p /etc/fstab #只打印非#开头的行
sed /^#/d /etc/fstab #删除以#开头的行 (注意与上一行的结果不同)
seq 10 |sed ‘3,8i xyz\nasd’ #在第3至第8行的每行前面加上xyz,再换行加上asd
seq 10 |sed ‘3,8a xyz’ #在第3至第8行的后面加上xyz
seq 10 |sed ‘3,8c xyz’ #将第3至第8行替换为xyz
seq 10 |sed ‘5d’ #第5行删除,其他行显示
seq 10 |sed ‘5!d’#对数字5取反 则第5行不删除 其他行都删除
sed s#k#replaced# passwd 将passwd文件中每一行的第一个单词k替换为replaced
sed s#k#replaced#g passwd 将passwd文件中所有单词k都替换为replaced
sed ‘s#k#replaced#gw bak’ passwd 将passwd文件中单词k全部替换为replaced 并在当前目录保存模式匹配的行至bak文件
sed ‘s#nologin#&er#’ passwd 将passwd文件中每一行的第一个单词nologin替换为nologiner &表示后向引用
sed ‘s/quiet/& net.ifnames=0/’ /etc/default/grub 在/etc/default/grub文件 quiet内容的后面加上’ net.ifnames=0′
sed ‘/GRUB_CMDLINE_LINUX/s/”$/ net.ifnames=0 &/’ /etc/default/grub
#该命令单引号内为’地址命令’格式
#地址为匹配/GRUB_CMDLINE_LINUX/这一行
#命令为s/”$/ net.ifnames=0 &/
# “$表示最后一个引号 s/”$/ net.ifnames=0&/表示在最后一个引号的前面加上” net.ifnames=0″
sed -r ‘/GRUB_CMDLINE_LINUX/s/(.*)”/\1 net.ifnames=0″/’ /etc/default/grub
#在GRUB_CMDLINE_LINUX所在行 (最后一个)引号前面的内容加上 net.ifnames=0
ifconfig eth0|sed -n ‘2p’|sed ‘s/.*inet //’|sed ‘s/ netmask.*//’
#第一次sed打印第二行 第二次将.*inet 替换为空 第三次sed将 netmask.*替换为空
#可合并为ifconfig eth0|sed -n ‘2p’|sed -e ‘s/.*inet //’ -e ‘s/ net.*//’
sed -r -e ‘s/^#(NameVirtualHost)/\1/’ -e ‘/^#<VirtualHost/,/^#<\/VirtualHost/s/#//’ /etc/httpd/conf/httpd.conf
sed -r -e ‘/#NameVirtualHost \*:80/s/#+//’ -e ‘/#<VirtualHost \*:80>/,/#<\/VirtualHost>/s/#+//’ httpd.conf
开启扩展正则 删除#(NameVirtualHost)所在行前面的空格 并删除#<VirtualHost \*:80> 到#<\/VirtualHost>行前面的#
sed -i.bak “/^# Source/i alias cdnet=’cd /etc/sysconfig/network-scripts'” .bashrc
#seq 10 |sed ‘3,8i xyz\nasd’
#将alias cdnet=’cd /etc/sysconfig/network-scripts’内容写入.bashrc文件# Source所在行的上一行
sed “s/bash/$USER/g” passwd
#调用变量$USER做替换 注意引用变量时使用双引号
awk:Aho, Weinberger, Kernighan,报告生成器,格式化文本输出
awk [options] ‘BEGIN{ action;… } pattern{ action;… } END{ action;… }’ file …
选项:
-F 指明输入时用到的字段分隔符
-v var=value: 自定义变量
pattern和action:
• pattern部分决定动作语句何时触发及触发事件
BEGIN,END
• action statements对数据进行处理,放在{}内指明
print, printf
分割符、域和记录
• awk执行时,由分隔符分隔的字段(域)标记$1,$2..$n称为域标识。$0为所有域
• 省略action,则默认执行 print $0 的操作
记录与字段
默认以换行符作为记录分隔符时 一行为一条记录 而一条记录又有多个字段
如下的文本信息
a,b,c;d,e,f;
g,h,i;k,l,m;
以换行符为记录分隔符 则有2个记录
以分号为记录分隔符 则有4个记录
每条记录以逗号作分隔符 则有三个字段
df | awk -F” ” ‘{print $5}’ #以空格为分隔符 分别打印每行的第5个字段 总体命令效果为打印df命令第5列的内容
df | awk -v FS=” ” -v OFS=’–‘ ‘{print $6,$1,$5}’ #以空格为分隔符 打印df命令第6列 第1列 第5列的内容 输出内容用–作分隔符
# -F” ” -v FS=” ” 注意格式 (╯‵□′)╯︵┻━┻
awk -F’:’ ‘{print $1″\t”$3}’ passwd #以冒号为分隔符 打印passwd文件第1列和第3列的内容 中间用制表符隔开
awk -F: ‘{print $(NF-1)}’ /etc/passwd #NF为字段总数 NF-1表示倒数第二个字段 整条命令表现为打印倒数第二列
awk -F: ‘{sex=”male”;print $1,sex,age;age=18}’ /etc/passwd #先后定义sex和age变量再打印
awk -F: ‘{printf “%-20s %10d\n”,$1,$3}’ /etc/passwd #对passwd文件第一列和第三列按一定格式打印,第一列左对齐留20个字符 第三列留10个字符
条件表达式(三目表达式):selector?if-true-expression:if-false-expression
awk -F: ‘{$3>=1000?usertype=”Common User”:usertype=”Sysadmin or SysUser”;printf “%-15s:%-s\n”,$1,usertype}’ /etc/passwd
#三目表达式 UID大于1000为普通用户 否则为系统用户
awk -F: ‘(NR>=10&&NR<=20){print NR,$1}’ /etc/passwd
#显示passwd文件第10至第20行
awk控制语句 注意格式 (╯‵□′)╯︵┻━┻
{ statements;… } 组合语句
if(condition) {statements;…}
if(condition) {statements;…} else {statements;…}
while(conditon) {statments;…}
do {statements;…} while(condition)
for(expr1;expr2;expr3) {statements;…}
break
continue
delete array[index]
delete array
awk -F: ‘{if($3>=1000) {printf “Common user: %s\n”,$1} else {printf “root or Sysuser: %s\n”,$1}}’ /etc/passwd
awk ‘/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}’ /etc/grub2.cfg
#取grub文件中以linux16开头的行 遍历所有字段 打印字段与字符长度
awk数组
若要遍历数组中的每个元素,要使用for循环
for(var in array) {for-body}
注意:var会遍历array的每个索引
示例:
awk ‘BEGIN{weekdays[“mon”]=”Monday”;weekdays[“tue”]=”Tuesday”;for(i in weekdays) {print weekdays[i]}}’
#创建weekdays数组 并遍历数组内所有元素
netstat -tan | awk ‘/^tcp/{state[$NF]++}END{for(i in state) { print i,state[i]}}’
#创建state数组 以netstat命令结果的最后一个字段作为索引,对应的值默认为空 ++以后变为1
#因此可用state数组统计不同连接状态的个数 其中状态值为索引,数值为对应状态出现的个数
#通用知识点: ARRAY[INDEX]++ 数组可以统计INDEX状态数据的个数 因此统计网站不同ip的访问次数可用以下命令来实现
awk ‘{ip[$1]++}END{for(i in ip) {print i,ip[i]}}’ /var/log/httpd/access_log
软件包管理
- rpm包安装 : rpm -ivh $PACKAGE_PATH
- yum命令 可解决安装软件包时的依赖问题
- 源码包编译安装 自定义程度较高 适合高级用户
常用yum命令
yum search http
yum install httpd
yum repolist
yum groupinstall “Development Tools”
yum clean all
源码包编译安装
关键步骤 ./configure && make && make install
预先准备编译环境 yum groupinstall “Development Tools”
下载源码包 wget https://mirrors.tuna.tsinghua.edu.cn/apache//httpd/httpd-2.4.29.tar.bz2
解压源码包 tar -xjf httpd-2.4.29.tar.bz2
cd httpd-2.4
./configure –prefix=/apps/httpd24 –enable-http2
#通过选项传递参数,指定启用特性、安装路径等;执行时会参考用户的指定以及Makefile.in文件生成Makefile
#检查依赖到的外部环境,如依赖的软件包 若此步骤提示缺少某个包 应安装该包的开发包 yum -y install apr-devel apr-util-devel pcre-devel
make -j 4 && {echo -e ‘\a’;sleep 1;echo -e ‘\a’}
#根据Makefile文件,构建应用程序 4线程并发编译加快速度,并在结束以后报警提示
make install
#复制文件到相应路径
#安装完成后可用 “PREFIX/bin/apachectl start”命令启动httpd服务器
#为操作方便可将该bin目录添加至环境变量: echo ‘PATH=/apps/httpd24/bin:$PATH’> /etc/profile.d/http24.sh && source /etc/profile.d/http24.sh
CentOS7 禁用防火墙 systemctl disable firewalld 关闭开机自启 systemctl stop firewalld
CentOS6 禁用防火墙 service iptables stop 关闭开机自启 chkconfig iptables off
----------------------------------------------------------------------------------------------------------------------------------
Python入门
知识点 : 99乘法表 list列表 pyenv 原反补码与异或运算 打印菱形与闪电 斐波那契数列 猴子吃桃 素数
定短期目标 未来一年内想达到什么样的水平
网络基础知识 IP TCP OSI HTTP
大公司看重算法 (数据结构 图论)
关系型数据库Sql –> 非关系型数据库NoSQL
WEB开发 前端可视化 JS
技术熟练以后 需要提高语言表达能力
Python怎么学
多写 2万行代码
核心问题 网上帖子找不到答案 需要自己多思考 结合所学知识 用代码实现
少看低水平博客 多查手册
慎用删除
用python3.5以上版本
java python c# 虚拟机语言
虚拟机:中间代码 可跨操作系统,中间代码再转化为机器指令
CPython iPython
PyPy JIT技术 动态优化 编译成本地代码 类似C语言
Jython Python源代码编译成Java字节码 可以跑在java虚拟机上
CentOS6 下python虚拟环境配置
CentOS6下默认为python2.6环境 不可升级 故考虑pyenv,该程序可提供python虚拟环境,方便项目部署和开发,同时不影响系统原有python.
STEP0 :pyenv使用编译方式安装 故需事先配置好编译环境
yum -y install git gcc make patch gdbm-devel openssl-devel sqlite-devel
readline-devel zlib-devel bzip2-devel
STEP1: root用户权限过大 pyenv设置不当会修改系统默认python版本 故创建普通用户登录运行pyenv
useradd python
STEP2: 以python用户登录以后安装pyenv curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
提示:
1.https://github.com/pyenv/pyenv-installer 有安装文档的说明
2.若curl出现 curl: (35) SSL connect error ,是nss版本低的问题,更新它。需配置一个有较新包的yum源
[updates]
name=CentOS-Updates
baseurl=https://mirrors.aliyun.com/centos/6.9/os/x86_64
gpgcheck=0
然后更新nss # yum update nss
STEP3: 将pyenv的bin目录加入环境变量
export PATH=”/home/python/.pyenv/bin:$PATH”
eval “$(pyenv init -)”
eval “$(pyenv virtualenv-init -)”
$ source ~/.bash_profile
STEP4: pyenv使用介绍
列出所有可用版本 $ pyenv install –list
在线安装指定版本 $ pyenv install 3.5.3
提示:
这样安装可能较慢,为提速可选用cache方法。
使用缓存方式安装 : 在~/.pyenv目录下,新建cache目录,放入下载好的待安装版本的文件。
不确定要哪一个文件,把下载的3个文件都放进去。可使用xftp或winscp等工具在windows与linux系统之间互传文件.
total 55204
-rw-rw-r–. 1 python python 20656090 Mar 19 16:08 Python-3.5.3.tar.gz
-rw-rw-r–. 1 python python 15213396 Mar 19 16:08 Python-3.5.3.tar.xz
-rw-rw-r–. 1 python python 20656090 Mar 19 16:08 Python-3.5.3.tgz
随后再运行pyenv install 3.5.3 命令就可以很快执行
版本控制
显示当前的python版本$ pyenv version
显示所有可用的python版本$ pyenv versions
global 全局设置 $ pyenv global 3.5.3 该命令会将系统全局的python指定为353版本. 故不推荐root用户进行全局设置 CentOS6.5系统Python为2.6版本,使用了global就成了3.x,会带来很不好的影响。 此时可使用 pyenv global system将全局python版本改为系统python版本
shell 会话设置 影响只作用于当前会话,退出ssh登录就失效 $ pyenv shell 3.5.3
local 本地设置 在某一目录执行 pyenv local 3.5.3 则从该目录开始向下递归都继承这一设置。
Virtualenv 虚拟环境设置
为什么要使用虚拟环境? 因为刚才使用的Python353环境都是一个公共的空间,如果多个项目使用不同Python版本开发,或者使用不同的Python版本部署运行,或者使用同样的版本开发的但不同项目使用了不同版本的库,等等这些问题都会带来冲突。最好的解决办法就是每一个项目独立运行自己的“独立小环境”中。
pyenv virtualenv 3.5.3 mag353 使用python3.5.3版本创建出一个独立的虚拟空间。
$ pyenv versions
* system (set by /home/python/.pyenv/version)
3.5.3
3.5.3/envs/mag353
mag353
可以在版本列表中存在,就和3.5.3是一样的,就是一个版本了。 真实目录在~/.pyenv/versions/下,以后只要使用这个虚拟版本,包就会按照到这些对应的目录下去,而不是使用3.5.3。
指定magedu/projects/web/目录为ma353虚拟环境 该虚拟环境子目录会继承,父目录则没有
总结:local与虚拟环境的区别: 后者独立得更彻底. 前者只是版本独立,后者还将软件库独立. 即使是和前者相同版本,后者也可将项目所需的库单独存放. 而不影响这一版本的大环境.
pip 通用配置
pip是python的包管理器 默认连接python官方pypi网站,速度较慢.可指定为阿里云的pypi源:
linux下配置文件为~/.pip/pip.conf
windows下pip的配置文件为~/pip/pip.ini
pip.conf内容如下:
[global]
index-url=https://mirrors.aliyun.com/pypi/simple/
trusted-host=mirrors.aliyun.com
安装ipython
ipython 是增强的交互式Python命令行工具
pip命令安装ipython $ pip install ipython
启动ipython $ ipython
安装Jupyter
jupyter是基于WEB的交互式笔记本,其中可以非常方便的使用Python。 安装Jupyter,也会安装ipython.
$ pip install jupyter
$ jupyter notebook help
查看帮助命令可看到很多有用选项 如jupyter notebook password
$ jupyter notebook –ip=0.0.0.0 –no-browser
提示:若设置密码以后输入密码无法登录jupyter页面 可将启动jupyter窗口后提示信息里的token值粘贴至web页面
原码 反码 补码 负数的表示
原码:符号位+数值位
最高位为符号位 正数符号位为0 负数符号位为1
如8的原码为0 1000 -7的原码为1 0111
正数的反码和补码均与原码相同
负数的反码为 符号位不变 数值位按位取反
负数的补码为 在负数的反码基础上再加1
数字在计算机中以补码形式存储
例
+7 符号位0 数值为111
0111
-7 符号位1 数值位111
1111
反码1000
补码1001
~9的计算步骤
9=1001
其补码为01001
对其取反10110,这个数是在内存中存放的,现在需要装换成原码,既先减1,然后取反得
11010,符号位为1是负数,即-10
10^9的计算步骤
10^9表示10和9原码对应二进制位进行异或运算
异或运算的法则为:相同得0 不同得1
10 0000 1010
9 0000 1001
异或 0000 0011
最后结果为3
10^-9
10 0000 1010
-9 1000 1001
异或 1000 0011
最后结果为-3
内存管理
引用计数
垃圾回收 Garbage Collection 简称GC 慎用!!!
尽量少占用内存 内存占用过大会引起GC 影响程序性能
打印99乘法表
for i in range(1,10):
for j in range(1,i+1):
print(j,'x',i,'=',i*j,sep='',end='\t')
print()
print('-------------------------------------------------------------------------')
for i in range(1,10):
line=''
for j in range(i,10):
line+='{}x{}={:<2} '.format(i,j,i*j)
print('{:>72}'.format(line))
print('------------------------------------------------------------------------')
'''
打印99乘法表 需注意多处细节
1 根据左右上下三角分别确定行和列的上下限
2 输出结果可直接使用print函数 或对字符串进行拼接再打印
3 注意print函数的两种分隔符设定print(value, ..., sep=' ', end='\n',)
4 注意print函数默认为左对齐 若想右对齐 需使用print('{:>72}'.format())形式设定左右对齐方式(>表示右对齐)以及最长行占位数(72)
'''
for i in range(1,10):
print(' '*(i-1)*8,sep=' ',end='')
for j in range(i,10):
product=i*j #product是乘积的英文
if product>9:
end=' '
else:
end=' '
# product=str(product)+' '
# line+='{}x{}={}'.format(i,j,product)
print(i,'x',j,'=',product,sep='',end=end)
print()
'''最后一种右对齐不用format 需要更复杂的逻辑判断
1 乘积大于9的末尾空两格 小于等于9的空三格
2 因此每项式子的宽度都是8 为实现右对齐 可在列较少的行事先打印出空格,并关闭print本行的换行功能
至于空格数量 则是(i-1)*8 因为需补空格的数量刚好比行号i少1
3 此题不可眼高手低 需认真判断行列号的范围 并适当调整空格数
'''
输入若干数字 最后输出最大值或平均值
m=int(input('>>>'))
while True:
s=input('>>>')
if s:
n=int(s)
if n>m:
m=n
print('max is ',m)
else:
# print('max is ',m)
break
count=0
sum=0
while True:
s=input('>>>')
if s:
count+=1
sum+=int(s)
print('ave is ',sum/count)
else:
break
'''
输入若干数字 可用以下代码实现
while True:
s=input('>>>')
if s:
pass
else:
break
注意不要形成s=int(input('>>>'))的思维定式 若要求输入若干数字
应采用以上办法 输入为空则停止循环
'''
打印菱形或闪电
'''
*
***
*****
*******
*****
***
*
以下为规律分析:
用print函数打印 print为左对齐
故只需考虑 行号L 左侧空白数b 星号数s的数学关系即可
行号L 空白数b 星号数s 循环行号i
1 3 1 -3
2 2 3 -2
3 1 5 -1
4 0 7 0
5 1 5 1
6 2 3 2
7 3 1 3
规律总结
设总行数为n hn=n//2
i=L-4 故range函数可写为range(-hn,n-hn)
b=abs(i)
s=n-2*b
乘2 除2 最好用位运算<<1 >>1代替
下面倒三角的规律只需做小改动
建议将不同的项目分开写 改变量名很麻烦也很容易出错
*******
*****
***
*
***
*****
*******
'''
n=9
hn=n>>1
for i in range(-hn,n-hn):
b=abs(i)
s=n-(b<<1)
print(' '*b,'*'*s)
nd=7
hnd=nd>>1
for i in range(-hnd,nd-hnd):
bd=hnd-abs(i)
sd=nd-(bd<<1)
print(' '*bd,'*'*sd)
# print(bd,sd)
猴子吃桃问题
last=1
for i in range(9):
last=(last+1)<<1
print(last)
'''
猴子吃桃问题可用逆向思维(加一再乘二)实现
但应注意循环的次数是9次而不是10次
'''
100以内的斐波那契数列
a=1
b=1
c=0
print(a,b,sep='\n',end='\n')
while True:
c=a+b
if c>100:
break
a=b
b=c
print(c)
'''
根据斐波那契数列的定义 下次加和时前两位数各向后推一位
这句话翻译为编程语言就是a=b b=c 需好好体会
'''
斐波那契数列的第101项
# n=int(input('nst of fbnq>>>'))
n=101
a=1
b=1
# c=0
if n==1:
print(a)
elif n==2:
print(b)
else:
for i in range(n-2):
c=a+b
a=b
b=c
print(c)
判断质数
a=int(input('输入一个数,判断是否为质数'))
if a<2:
print('注意,0和1既非素数也非合数')
elif a==2:
print(a,'是质数')
else:
# for i in range(2,a):
for i in range(2,int(a**0.5)+1):
if a%i ==0:
print(a,'不是质数')
break
# elif i<a-1:
# continue
# else :
# print(a,'是质数')
else :
print(a,'是质数')
'''本题两点点评
1 判断质数的核心算法,数n对2到n-1取模,若发现可以整除,直接跳出循环.循环结束后一直没有整除,则是质数.
注意最后的else应放在和if同级的位置 而不是if里面
2 数n对2到n-1取模 其实从2到根号n就够了 因为乘法具有交换律 超过根号n的位置
因为合数一定可以表示成两个数(除了1和它本身)相乘,这两个数必然有一个小于等于它的平方根。只要找到小于或等于的那个因数就行了
'''
10万以内的质数
import datetime
start=datetime.datetime.now()
count=1
for a in range(3,100000,2):#1
if a%10==5 and a>10:#2
continue
for i in range(3,int(a**0.5)+1,2):#3
if a%i ==0:
# print(a,'不是质数')
break
else :
# print(a,'是质数')
count+=1
pass
print(count)
end=datetime.datetime.now()
print(end-start)
'''
本题的几点优化方向
1 求质数 可以先舍去所有偶数 可减少一半的任务量
2 对于大于10的数 若个位数是5, 必然是5的倍数 可直接排除
3 数n对2到n-1取模 其实从2到根号n就够了 同时待测数中已无偶数,因此取模的数也不需要偶数
'''
python数据类型
数值型
int 长整型 无大小限制
float 双精度浮点数
complex 虚数单位为j 实部虚部皆为浮点数
bool int的子类 仅有True与False两个实例 对应1和0 可与整数直接运算
数字处理函数
int() 只取整数
无论正负 只取出整数部分 小数部分直接丢弃(Return an integer object constructed from a number or string x.For floating point numbers, this truncates towards zero)
因此无论是3.1还是3.9,int后皆为3
无论是-3.1还是-3.9,int后皆为-3
import math
math.floor()向下取整 math.ceil向上取整
这两个函数取整时不考虑误差 在数轴上,小数两边各有一个整数 floor函数取比该数小的整数(Return the floor of x, the largest integer less than or equal to x),ceil函数则取比该数大的整数(Return the ceiling of x, the smallest integer greater than or equal to x.)
floor与ceil的原意为地板与天花板 可形象地表示这一大小边界
因此无论是3.1还是3.9 floor后皆为3 ceil后皆为4
无论是-3.1还是-3.9 floor后皆为-4 ceil后皆为-3
round() 四舍六入五取偶
无论正负数 以0.5为界 小数部分小于0.5则舍去 大于0.5则整数绝对值进一
等于0.5则取与其最接近的偶数(为减小误差)
因此2.5 按照取偶数的原则 结果是2
1.5 取偶为2 并非一般的四舍五入
-2.5 取偶为-2
// floor division 地板除
对自然除法得到的小数再做int处理 即对小数向下取整
9//2=4 注意9//-2=-5
power(x,y) == x**y
math.aqrt() 平方根
math.pi 圆周率π
math.e 自然常数
进制函数 bin() oct() hex() 返回值为字符串
type() 返回类型,而不是字符串
列表list 链表linked list 队列queue 栈stack
列表 存于连续空间 每个元素有确定的线性增长的地址 表长为n 则索引值为0~n-1 可从中间插入元素 但需向后移位(插入数据较为麻烦) 支持随机查找
链表 不需存于连续空间 由指针指向下一位元素 末位元素指针为空 通过修改指针可方便地插入数据 但不支持随机查找
队列 特殊的线性表 只可队首删除 队尾插入 先进先出
栈 有底无盖的容器 进栈出栈都走栈顶(top) 先进后出
列表list
一列队伍 列表内个体称作元素 元素可为任意数据类型(数字 字符串 对象 列表)
元素有序,可用索引 线性结构 用[]表示 可变的
列表的各种操作
增
初始化: lista=[1,’2′,3.4,5+7j,True] 或 lst = list(range(5))
方法:
尾部追加 append(obj) O(1)
指定索引位置插入 insert(index,obj) O(n)
extend(iteratable) 将可迭代对象的元素追加进来,返回None 就地修改
+ 加号两边跟上列表 两个列表连接起来产生新的列表,原列表不变
lista*n 将列表lista元素重复n次,返回新的列表,原列表不变
删
remove(value) -> None 从左至右查找第一个匹配value的值,移除该元素,返回None
pop([index]) -> item 不指定索引index,就从列表尾部弹出一个元素 指定索引index,就从索引处弹出一个元素,索引超界抛出IndexError错误
clear() -> None 清除列表所有元素,剩下一个空列表
改
list[index] = value 通过赋值的方式该元素值
reverse() -> None 将列表元素反转,返回None
sort(key=None, reverse=False) -> None 对列表元素进行排序,就地修改,默认升序 reverse为True,反转,降序
查
lista[index] 使用索引可直接访问 注意索引范围 0~n-1 -1~-n为负索引,表示倒数第一至倒数第n
index(value,[start,[stop]])通过值value,从指定区间([start,[stop]为前闭后开区间)查找列表内的元素是否匹配 匹配第一个就立即返回 索引匹配不到,抛出异常ValueError
count(value) 返回列表中匹配value的次数
len() 返回列表长度