愚蠢的地球人

Linux用户用户组以及文件权限

Linux是一个多用户、多任务的操作系统。用户在系统中是分角色的,在Linux系统中,由于角色不同,权限和所完成的任务也不同;比如一台Linux服务器,上面有 FTP 用户、系统管理员、超级管理员 root、web 用户、常规普通用户等,不同用户所具有的权限也不同,要完成不同的任务得需要不同的用户。多用户既可以本地登录也可以通过远程来登录。多用户系统对系统管理更方便更安全,比如某用户下的某个文件不想让其它用户看到,只需要设置一下文件的权限,只有本用户可读可写就行了。

Linux的用户分为以下几类:
超级管理员用户 root:系统唯一,是真实的,可以登录系统,可以操作系统任何文件和命令,拥有最高权限;
虚拟用户:虚拟用户实际上就是去掉了登录SHELL权限的用户,因为默认登录shell是 '/sbin/nologin'。他没有能力登录系统,但可以进行其他任何操作,是系统运行不可缺少的用户,比如 nobody 和 ftp 等,我们访问服务器上的的 Web Server,就是 nobody 用户;我们匿名访问 FTP Server 时,会用到用户 ftp 或 nobody ;这类用户有些是系统自身拥有的,而非后来添加的,当然我们也可以添加虚拟用户;
普通真实用户:这类用户能登录系统,但只能操作自己家目录的内容;权限有限;这类用户都是系统管理员自行添加的;

用户组(group)就是具有相同特征的用户(user)的集合体;比如有时我们要让多个用户具有相同的权限,比如查看、修改某一文件或执行某个命令,这时我们需要用户组,我们把用户都定义到同一用户组,我们通过修改文件或目录的权限,让用户组具有一定的操作权限,这样用户组下的用户对该文件或目录都具有相同的权限,这是我们通过定义组和修改文件的权限来实现的;

用户和用户组的对应关系是:一对一、多对一、一对多或多对多;
一对一:某个用户可以是某个组的唯一成员;
多对一:多个用户可以是某个唯一的组的成员,不归属其它用户组;
一对多:某个用户可以是多个用户组的成员;
多对多:多个用户对应多个用户组,并且几个用户可以是归属相同的组;

查看用户和用户组的命令:
whoami 查看当前登录用户名,例如:
liugeng@liugeng-Ubuntu:~$ whoami
liugeng
groups 查看当前登录用户的组内成员,例如:
liugeng@liugeng-Ubuntu:~$ groups liugeng
liugeng : liugeng adm cdrom sudo dip plugdev lpadmin sambashare
liugeng@liugeng-Ubuntu:~$ groups root
root : root

Linux的用户信息保存在/etc/passwd文件中,/etc/shadow文件存放的是用户密码相关信息。
/etc/passwd文件格式:
用户名:密码:UID:GID:用户信息:HOME目录路径:用户shell
其中UID为0则是用户root,1~499为系统用户,500以上为普通用户
/etc/shadow保存用户密码信息,包括加密后的密码,密码过期时间,密码过期提示天数等。


/etc/group 用户组(group)配置文件;
/etc/gshadow 用户组(group)的影子文件;
/etc/group 文件是用户组的配置文件,内容包括用户和用户组,并且能显示出用户是归属哪个用户组或哪几个用户组,因为一个用户可以归属一个或多个不同的用户组;同一用户组的用户之间具有相似的特征。比如我们把某一用户加入到root用户组,那么这个用户就可以浏览root用户家目录的文件,如果root用户把某个文件的读写执行权限开放,root用户组的所有用户都可以修改此文件,如果是可执行的文件,root用户组的用户也是可以执行的;用户组的特性在系统管理中为系统管理员提供了极大的方便,但安全性也是值得关注的,如某个用户下有对系统管理有最重要的内容,最好让用户拥有独立的用户组,或者是把用户下的文件的权限设置为完全私有;另外root用户组一般不要轻易把普通用户加入进去。
/etc/group 的格式如下:
group_name:passwd:GID:user_list
第一字段:用户组名称;
第二字段:用户组密码;
第三字段:GID(Group ID);
第四字段:用户列表,每个用户之间用,号分割;本字段可以为空;如果字段为空表示用户组为GID的用户名;
用户登录后,/etc/passwd 文件里的GID为用户的初始用户组。
用户的初始用户组这一事实不会在 /etc/group 中体现。


管理用户(user)的工具或命令:
useradd 添加用户
adduser 添加用户
passwd 为用户设置密码
usermod 修改用户命令,可以通过usermod 来修改登录名、用户的家目录等等;
pwcov 同步用户从/etc/passwd 到/etc/shadow
pwck 校验用户配置文件/etc/passwd 和/etc/shadow 文件内容是否合法或完整;
pwunconv 是 pwcov 的立逆向操作,是从/etc/shadow和 /etc/passwd 创建/etc/passwd ,然后会删除 /etc/shadow 文件;
finger 查看用户信息工具
id 查看用户的UID、GID及所归属的用户组
chfn 更改用户信息工具
su 用户切换工具
sudo 是通过另一个用户来执行命令(execute a command as another user),sudo 后面直接执行命令;
visudo 是编辑 /etc/sudoers 的命令,也可以不用这个命令,直接用vi 来编辑 /etc/sudoers 的效果是一样的;
 

管理用户组(group)的工具或命令:
groupadd 添加用户组;
groupdel 删除用户组;
groupmod 修改用户组信息
groups 显示用户所属的用户组
grpck grpconv 通过/etc/group和/etc/gshadow 的文件内容来同步或创建/etc/gshadow ,如果/etc/gshadow 不存在则创建;
grpunconv 通过/etc/group 和/etc/gshadow 文件内容来同步或创建/etc/group ,然后删除gshadow文件;
 

/etc/skel目录是存放用户启动文件的目录,这个目录是由root权限控制,当我们添加用户时,这个目录下的文件自动复制到新添加的用户的家目录下;/etc/skel 目录下的文件都是隐藏文件,也就是类似.file格式的;我们可通过修改、添加、删除/etc/skel目录下的文件,来为用户提供一个统一、标准的、默认的用户环境;

liugeng@liugeng-Ubuntu:~$ ls -la /etc/skel/
总用量 40
drwxr-xr-x   2 root root  4096 12月 10 02:35 .
drwxr-xr-x 146 root root 12288 12月 15 11:43 ..
-rw-r--r--   1 root root   220 9月   1  2015 .bash_logout
-rw-r--r--   1 root root  3771 9月   1  2015 .bashrc
-rw-r--r--   1 root root  8980 4月  20  2016 examples.desktop
-rw-r--r--   1 root root   807 6月   7  2019 .profile


/etc/skel 目录下的文件,一般是我们用 useradd 和 adduser 命令添加用户(user)时,系统自动复制到新添加用户(user)的家目录下;如果我们通过修改 /etc/passwd 来添加用户时,我们可以自己创建用户的家目录,然后把 /etc/skel 下的文件复制到用户的家目录下,然后要用 chown 来改变新用户家目录的属主;

/etc/login.defs 配置文件是当创建用户时的一些规划,比如创建用户时,是否需要家目录,UID和GID的范围;用户的期限等等,这个文件是可以通过root来定义的;


用户用户组文件权限操作命令详解:

切换有效用户组:
[root@Ubuntu]#newgrp 用户组名
要离开新的有效用户组,则输入exit回车。

新建用户:
[root@Ubuntu]#useradd 用户名 -g 初始用户组 -G 其他用户组(修改/etc/group) -c 用户说明 -u 指定UID

建完用户需要为用户设置密码:
[root@Ubuntu]#passwd 用户名

用户要修改自己密码:
[root@Ubuntu]#passwd

修改用户信息:
[root@Ubuntu]#usermod 参数 用户名
参数:
 -c 说明
 -g 组名 初始用户组
 -e 过期日期 格式:YYYY-MM-DD
 -G 组名 其他用户组
 -l 修改用户名
 -L 锁定账号(在/etc/shadow文件中用户对应密码密码串的前面加上两个叹号(!!))
 -U 解锁

删除用户:
[root@Ubuntu]#userdel [-r] 用户名
其中,参数-r为删除用户的home目录。
其实,可能在系统其他地方也有该用户文件,要完整删除一个用户和其文件要先找到属于他的文件:
[root@Ubuntu]#find / -user 用户名
然后删除,再运行userdel删除用户。

查看可用shell:
[root@Ubuntu]#chsh -l
修改自己的shell命令:
[root@Ubuntu]#chsh -s

查看自己或某人UID/GID信息:
[root@Ubuntu]#id [用户名]
返回信息中groups为有效用户组

新增用户组:
[root@Ubuntu]#groupadd 用户组名

修改用户组名:
[root@Ubuntu]#groupmod -n 名称

删除用户组:
[root@Ubuntu]#groupdel 用户组名

设置用户组密码:
[root@Ubuntu]#gpasswd 用户组名

如果gpasswd加上参数则有其他功能

设置用户组管理员:
[root@Ubuntu]#gpasswd -A 用户名 用户组名

添加某帐号到组:
[root@Ubuntu]#gpasswd -M 用户名 用户组名

从组中删除某帐号:
[root@Ubuntu]#gpasswd -d 用户名 用户组名

passwd相关参数操作:
-l 锁用户
-u 解锁用户
-n 天数  密码不可改天数
-x 天数  密码过期天数
-w 天数  警告天数


文件权限操作命令详解:
先看个实例:
[root@Ubuntu]#ls -al
ls -al 命令是列出目录的所有文件,包括隐藏文件。隐藏文件的文件名第一个字符为'.'
-rw-r--r--  1 root root    81 08-02 14:54 gtkrc-1.2-gnome2
-rw-------  1 root root   189 08-02 14:54 ICEauthority
-rw-------  1 root root    35 08-05 10:02 .lesshst
drwx------  3 root root  4096 08-02 14:54 .metacity
drwxr-xr-x  3 root root  4096 08-02 14:54 nautilus

列表的列定义如下:
[权限属性信息] [连接数] [拥有者] [拥有者所属用户组] [大小] [最后修改时间] [文件名]

权限属性列表为10个字符:
第一个字符表示文件类型,d为目录 -为普通文件 l为连接 b为可存储的接口设备 c为键盘鼠标等输入设备
2、3、4个字符表示所有者权限,5、6、7个字符表示所有者同组用户权限,8、9、10为其他用户权限
第二个字符表示所有者读权限,如果有权限则为r,没有权限则为-
第三个字符表示所有者写权限,如果有权限则为w,没有权限则为-
第四个字符表示所有者执行权限,如果有权限则为x,没有权限则为-
第五个字符表示所有者同组用户读权限,如果有权限则为r,没有权限则为-
第六个字符表示所有者同组用户写权限,如果有权限则为w,没有权限则为-
第七个字符表示所有者同组用户执行权限,如果有权限则为x,没有权限则为-
第八个字符表示其他非同组读权限,如果有权限则为r,没有权限则为-
第九个字符表示其他非同组写权限,如果有权限则为w,没有权限则为-
第十个字符表示其他非同组执行权限,如果有权限则为x,没有权限则为-

修改文件所属组:
[root@Ubuntu]#chgrp [-R] 组名 文件名
其中-R为递归设置

修改文件的所有者和组:
[root@Ubuntu]#chown [-R] 用户[:用户组] 文件名

修改文件访问权限:
[root@Ubuntu]#chmod [-R] 0777 文件名

linux 查看用户及用户组的方法
------------------------------------------------------------------
whois
功能说明:查找并显示用户信息。
语  法:whois [帐号名称]
补充说明:whois指令会去查找并显示指定帐号的用户相关信息,因为它是到Network Solutions 的WHOIS数据库去查找,所以该帐号名称必须在上面注册方能寻获,且名称没有大小写的差别。
------------------------------------------------------------------
whoami
功能说明:显示用户名称。
语  法:whoami [--help][--version]
补充说明:显示自身的用户名称,本指令相当于执行"id -un"指令。
参  数:
--help  在线帮助。
--version  显示版本信息。
------------------------------------------------------------------
who
功能说明:显示目前登入系统的用户信息。
语  法:who [-Himqsw][--help][--version][am i][记录文件]
补充说明:执行这项指令可得知目前有那些用户登入系统,单独执行who指令会列出登入帐号,使用的    终端机,登入时间以及从何处登入或正在使用哪个X显示器。
参  数:
-H或--heading  显示各栏位的标题信息列。
-i或-u或--idle  显示闲置时间,若该用户在前一分钟之内有进行任何动作,将标示成"."号,如果该用户已超过24小时没有任何动作,则标示出"old"字符串。
-m  此参数的效果和指定"am i"字符串相同。
-q或--count  只显示登入系统的帐号名称和总人数。
-s  此参数将忽略不予处理,仅负责解决who指令其他版本的兼容性问题。
-w或-T或--mesg或--message或--writable  显示用户的信息状态栏。
--help  在线帮助。
--version  显示版本信息。
------------------------------------------------------------------
w
功能说明:显示目前登入系统的用户信息。
语  法:w [-fhlsuV][用户名称]
补充说明:执行这项指令可得知目前登入系统的用户有那些人,以及他们正在执行的程序。单独执行w
指令会显示所有的用户,您也可指定用户名称,仅显示某位用户的相关信息。
参  数:
-f  开启或关闭显示用户从何处登入系统。
-h  不显示各栏位的标题信息列。
-l  使用详细格式列表,此为预设值。
-s  使用简洁格式列表,不显示用户登入时间,终端机阶段作业和程序所耗费的CPU时间。
-u  忽略执行程序的名称,以及该程序耗费CPU时间的信息。
-V  显示版本信息。
------------------------------------------------------------------
finger
finger 命令的功能是查询用户的信息,通常会显示系统中某个用户的用户名、主目录、停滞时间、登录时间、登录shell等信息。如果要查询远程机上的用户信息,需要在用户名后面接“@主机名”,采用[用户名@主机名]的格式,不过要查询的网络主机需要运行finger守护进程。
该命令的一般格式为:
finger [选项] [使用者] [用户@主机]
命令中各选项的含义如下:
-s 显示用户的注册名、实际姓名、终端名称、写状态、停滞时间、登录时间等信息。
-l 除了用-s选项显示的信息外,还显示用户主目录、登录shell、邮件状态等信息,以及用户主目录下的.plan、.project和.forward文件的内容。
-p 除了不显示.plan文件和.project文件以外,与-l选项相同。 
[例]在本地机上使用finger命令。
$ finger xxq
Login: xxq Name:
Directory: /home/xxq Shell: /bin/bash
Last login Thu Jan 1 21:43 (CST) on tty1
No mail.
No Plan. 
$ finger
Login Name Tty Idle Login Time Office Office Phone
root root *1 28 Nov 25 09:17
……
------------------------------------------------------------------
vlock(virtual console lock)
功能说明:锁住虚拟终端。
语  法:vlock [-achv]
补充说明:执行vlock指令可锁住虚拟终端,避免他人使用。
参  数:
-a或--all  锁住所有的终端阶段作业,如果您在全屏幕的终端中使用本参数,则会将用键盘
切换终端机的功能一并关闭。
-c或--current  锁住目前的终端阶段作业,此为预设值。
-h或--help  在线帮助。
-v或--version  显示版本信息。
------------------------------------------------------------------
usermod
功能说明:修改用户帐号。
语  法:usermod [-LU][-c <备注>][-d <登入目录>][-e <有效期限>][-f <缓冲天数>][-g <群组>][-G <群组>][-l <帐号名称>][-s ][-u ][用户帐号]
补充说明:usermod可用来修改用户帐号的各项设定。
参  数:
-c<备注>  修改用户帐号的备注文字。
-d登入目录>  修改用户登入时的目录。
-e<有效期限>  修改帐号的有效期限。
-f<缓冲天数>  修改在密码过期后多少天即关闭该帐号。
-g<群组>  修改用户所属的群组。
-G<群组>  修改用户所属的附加群组。
-l<帐号名称>  修改用户帐号名称。
-L  锁定用户密码,使密码无效。
-s  修改用户登入后所使用的shell。
-u  修改用户ID。
-U  解除密码锁定。
------------------------------------------------------------------
userdel
功能说明:删除用户帐号。
语  法:userdel [-r][用户帐号]
补充说明:userdel可删除用户帐号与相关的文件。若不加参数,则仅删除用户帐号,而不删除相关文件。
参  数:
-f  删除用户登入目录以及目录中所有文件。
------------------------------------------------------------------
userconf
功能说明:用户帐号设置程序。
语  法:userconf [--addgroup <群组>][--adduser <用户ID><群组><用户名称>][--delgroup <群组>][--deluser <用户ID>][--help]
补充说明:userconf实际上为linuxconf的符号连接,提供图形界面的操作方式,供管理员建立与管理各类帐号。若不加任何参数,即进入图形界面。
参  数:
--addgroup<群组>  新增群组。
--adduser<用户ID><群组><用户名称>  新增用户帐号。
--delgroup<群组>  删除群组。
--deluser<用户ID>  删除用户帐号。
--help  显示帮助。
------------------------------------------------------------------
useradd
功能说明:建立用户帐号。
语  法:useradd [-mMnr][-c <备注>][-d <登入目录>][-e <有效期限>][-f <缓冲天数>][-g <群组>][-G <群组>][-s ][-u ][用户帐号] 或 useradd -D [-b][-e <有效期限>][-f <缓冲天数>][-g <群组>][-G <群组>][-s ]
补充说明:useradd可用来建立用户帐号。帐号建好之后,再用passwd设定帐号的密码.而可用userdel删除帐号。使用useradd指令所建立的帐号,实际上是保存在/etc/passwd文本文件中。
参  数:
-c<备注>  加上备注文字。备注文字会保存在passwd的备注栏位中。 
-d<登入目录>  指定用户登入时的启始目录。
-D  变更预设值.
-e<有效期限>  指定帐号的有效期限。
-f<缓冲天数>  指定在密码过期后多少天即关闭该帐号。
-g<群组>  指定用户所属的群组。
-G<群组>  指定用户所属的附加群组。
-m  自动建立用户的登入目录。
-M  不要自动建立用户的登入目录。
-n  取消建立以用户名称为名的群组.
-r   建立系统帐号。
-s  指定用户登入后所使用的shell。
-u  指定用户ID。


深入理解sudo与su之间的区别

在Linux下对很多文件进行修改都需要有root(管理员)权限,但是很多人都不清楚sudo和su命令的区别,网上查了很多资料,归纳了一下,大致如下:


两个命令的最大区别是 sudo 命令需要输入当前用户的密码,su 命令需要输入 root 用户的密码。
另外一个区别是其默认行为,sudo 命令只允许使用提升的权限运行单个命令,而 su 命令会启动一个新的 shell,同时允许使用 root 权限运行尽可能多的命令,直到明确退出登录。

su 命令
su 命令的主要作用是让你可以在已登录的会话中切换到另外一个用户,这个工具可以让你在不登出当前用户的情况下登录为另外一个用户。
su 命令经常被用于切换到超级用户或 root 用户,也可以用于切换到任意非 root 用户。 su 的默认用户是 root,所以只需在终端直接输入 su 即可切换到 root 用户,su 命令要求输入的密码是 root 用户的密码,在输入正确的密码之后,su 命令会在终端的当前会话中打开一个子会话。
还有一种方法可以切换到 root 用户:运行 su - root
那么,su 命令与 su - 命令之间有什么区别呢?前者在切换到 root 用户之后仍然保持之前用户的环境,而后者则是创建一个新的环境(由 root 用户 ~/.bashrc 文件所设置的环境),相当于使用 root 用户正常登录。

sudo 命令
sudo 命令是用来获取临时的 root 权限,不过有时间限制,Ubuntu默认为一次时长15分钟。提示输入密码是当前用户的密码,而不是超级账户的密码。要求执行该命令的用户必须在 sudoers 中才可以。
sudo 的配置文件是 sudoers 文件,它允许系统管理员集中的管理用户的使用权限和使用的主机。它所存放的位置默认是在 /etc/sudoers,属性必须为0440。

sudo -i 和 sudo su 命令没有时间限制。执行该命令后提示符变为“#”而不是“$”。想退回普通账户时可以执行“exit”或“logout” 。
sudo -i 与 sudo - root、sudo -i root、sudo -、sudo root效果相同。
-i 是指更改 shell 环境参量为目标用户的,如果不指定用户则默认为 root。
sudo -i 运行后 PWD=/root
sudo su 运行后 PWD=/home/用户名(当前用户主目录)

sudo vs. su
两个命令的最大区别是:sudo 命令需要输入当前用户的密码,su 命令需要输入 root 用户的密码。
很明显,就安全而言,sudo 命令更好。例如,考虑到需要 root 访问权限的多用户使用的计算机。在这种情况下,使用 su 意味着需要与其他用户共享 root 用户密码,这显然不是一种好习惯。
而使用 sudo 命令就不一样了,你可以很好的处理以上的两种情况。鉴于 sudo 命令要求输入的是其他用户自己的密码,所以,不需要共享 root 密码。同时,想要阻止特定用户访问 root 权限,只需要调整 sudoers 文件中的相应配置即可。
其次,两个命令之间的另外一个区别是其默认行为。sudo 命令只允许使用提升的权限运行单个命令,而 su命令会启动一个新的 shell,同时允许使用 root 权限运行尽可能多的命令,直到明确退出登录。 因此,su 命令的默认行为是有风险的,因为用户很有可能会忘记他们正在以 root 用户身份进行工作,于是,无意中做出了一些不可恢复的更改(例如:对错误的目录运行 rm -rf 命令!)。

尽管 sudo 命令是以目标用户(默认情况下是 root 用户)的身份执行命令,但是它们会使用 sudoer 所配置的用户名来记录是谁执行命令。而 su 命令是无法直接跟踪记录用户切换到 root 用户之后执行了什么操作。

sudo 命令比 su 命令灵活很多,因为你甚至可以限制 sudo 用户可以访问哪些命令。换句话说,用户通过 sudo 命令只能访问他们工作需要的命令。而 su 命令让用户有权限做任何事情。 大概是因为使用 su 命令或直接以 root 用户身份登录有风险,所以,一些 Linux 发行版(如 Ubuntu)默认禁用 root 用户帐户。鼓励用户在需要 root 权限时使用 sudo 命令。如果你想在系统中启用 root 用户帐户(强烈反对,因为你可以使用 sudo 命令或 sudo su 命令),你必须手动设置 root 用户密码,可以使用以下命令:
sudo passwd root


OpenWRT路由器科学上网自动分流的工作原理

最近研究了一台刷了OpenWRT的路由器,里面有一个科学上网的工具引发了我的兴趣。
研究了好几天,终于把国内国外流量自动分流的原理弄清了。
很多东西都是个人的猜测,如有不对的地方,欢迎大家留言讨论。

OpenWRT科学上网自动分流主要是利用了如下几个工具:iptables、ipset、dnsmasq、pdnsd。我先来一个一个的解释一下这几个东东:

iptables是Linux系统自带的基于包过滤的防火墙工具,可以对流入、流出及流经服务器的数据包进行精细的控制。

ipset是iptables的扩展,它允许你创建某一类IP地址的集合,然后将这个集合交给iptables来处理。

dnsmasq是一个DNS缓存服务器,它可以将特定的域名发送给不同的dns服务器进行解析,不仅如此,它还可以把解析出来的IP地址存储在指定的ipset中。

pdnsd也是一个DNS缓存服务器,相对于dnsmasq,pdnsd的优点是可以使用TCP方式来查询DNS,但是pdnsd无法设置ipset,所以需要将dnsmasq和pdnsd两个结合起来使用。

弄清楚了这些工具的作用,OpenWRT路由器科学上网自动分流的工作原理就不难理解了:

首先,科学上网的进程启动之后会自动将需要走代理的域名地址添加到dnsmasq的conf-dir目录下的一些名为*.conf的文件中,内容如下:
server=/google.com/127.0.0.1#1053
ipset=/google.com/gfwlist
第一行意思是解析google.com这个域名时不使用默认的DNS服务器,而是将查询请求转发到127.0.0.1#1053(pdnsd侦听的端口),由pdnsd来负责解析。
第二行意思是将google.com解析出来的IP地址添加到一个名为gfwlist的ipset集合里面。
这样,需要走代理的域名使用pdnsd来解析,不需要走代理的域名使用宽带运营商默认的DNS来解析,实现了域名解析的分流。

然后,它会修改iptables的转发规则,将gfwlist这个ipset添加到iptables的NAT规则列表中,利用iptables来转发这个ipset中的数据。
我们来查看一下路由器的iptables如何处理名为gfwlist的这个ipset:

More...


用Python读取图片的Exif时间给相册图片批量重命名

现代的智能手机拍出来的照片文件默认的命名方式是类似:“IMG_20191201_150800.jpg”这样的结构,但是我发现我手机里好多老照片没有遵循这一命名规则。

不仅前缀五花八门,而且很多老的手机默认不是以日期时间而是以一个递增的序号来命名。强迫症的我无法接受这些乱七八糟的命名,于是我写了一个Python程序来批量对这些图片来重命名。

读取一个图片文件的修改时间有两种方式,一是直接读取文件本身的修改时间,二是读取图像Exif信息中的时间。

第一种方式读取方法最简单,但是有一个很严重的问题:文件的修改时间并没有储存在文件本身,而是储存在磁盘文件系统的文件表里面,当你将一个文件从一个文件系统复制到另一个文件系统的时候,原来的时间戳会丢失:比如说当你把一个图片文件从手机拷贝到电脑或者当你把照片从电脑拷贝到手机的时候,文件的修改时间就会变成文件复制的时间。

More...


用Python批量压缩图片来给你的手机相册瘦身

我每次换手机都会把旧手机里的照片备份出来拷贝进新手机里,于是现在我的手机里面就有了几十个GB的照片。但是以手机摄像头的成像质量,一张照片动不动就5到10MB的尺寸实在是太浪费手机的存储空间了。

于是我开始在网上寻找能给相册瘦身的APP,终于我找到了一款叫“相册管家”的应用。这是一个腾讯出品的软件,功能非常多,照片压缩只是它附带的一个小功能。

More...


家用NAS利用公网IPV6外网访问

通过IPV6从外网访问家里的NAS需要做两件事:一是解决IPV6的DDNS,二是配置路由器的防火墙。


先说DDNS,我用的是群晖的NAS,动态域名用的是Dnspod,但是群晖NAS自带的DDNS不支持Dnspod的IPV6更新。

只能自己写脚本来解决这个问题,直接上代码: 【以下代码在群晖DSM6系统下测试正常,其他设备可能需要做修改】

#!/bin/bash
#Dnspod DDNS6 with BashShell
#改编自Github:https://github.com/kkkgo/dnspod-ddns-with-bashshell
#CONF START
#API_ID和API_Token在dnspod的控制台 -> 用户中心 -> 安全设置 -> API Token 中获取
API_ID="12345"
API_Token="abcdef123456abcdef123456abcdef123456"
domain="yourdomain.com"
host="yourhost"
DEV="eth0"
#CONF END
date

IPREX="((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))"

DEVIP=$(ip -6 addr list scope global $DEV | grep -v " fd" | grep inet6 | awk '{print $2}' | head -n 1)
if (echo $DEVIP | grep -qEvo "$IPREX");then
  echo "Get $DEV inet6 IP Failed."
  exit
else DEVIP=$(echo $DEVIP | grep -Eo "$IPREX" | head -n 1)
fi
echo "[DEV IP]:$DEVIP"

DNSTEST=$(nslookup -q=AAAA $host.$domain)
if (echo $DNSTEST | grep -qEvo "$IPREX");then
  echo "Get $host.$domain DNS Failed."
  exit
else DNSIP=$(echo $DNSTEST | grep -Eo "$IPREX" | tail -n 1)
fi
echo "[DNS IP]:$DNSIP"

if [ "$DNSIP" == "$DEVIP" ];then
  echo "IP SAME IN DNS,SKIP UPDATE."
  exit
fi

token="login_token=${API_ID},${API_Token}&format=json&domain=${domain}&sub_domain=${host}"
Record=$(curl -s -k -X POST https://dnsapi.cn/Record.List -d "${token}")
iferr=$(echo ${Record#*code} | cut -d'"' -f3)
if [ "$iferr" == "1" ];then
  record_ip=$(echo ${Record#*value} | cut -d'"' -f3)
  echo "[API IP]:$record_ip"
  if [ "$record_ip" == "$DEVIP" ];then
    echo "IP SAME IN API,SKIP UPDATE."
    exit
  fi
  record_id=$(echo ${Record#*\"records\"\:\[\{\"id\"} | cut -d'"' -f2)
  record_line_id=$(echo ${Record#*line_id} | cut -d'"' -f3)
  echo Start DDNS update...
  ddns=$(curl -s -k -X POST https://dnsapi.cn/Record.Modify -d "${token}&record_id=${record_id}&record_line_id=${record_line_id}&value=${DEVIP}&record_type=AAAA")
  ddns_result="$(echo ${ddns#*message\"} | cut -d'"' -f2)"
  echo -n "DDNS upadte result:$ddns_result "
  echo $ddns | grep -Eo "$IPREX" | tail -n 1
else echo -n Get $host.$domain error :
  echo $(echo ${Record#*message\"}) | cut -d'"' -f2
fi

将以上代码保存为.sh文件,然后在NAS系统里添加一个计划任务:

More...


电脑BIOS系统引导过程详解

目前个人电脑主要的系统引导方式有两种:传统的Legacy BIOS和新型的UEFI BIOS。

要了解引导方式首先要了解一下磁盘分区表格式,一般来说,磁盘分区表有两种格式:MBR和GPT。MBR分区表在Windows操作系统下最多支持4个主分区(只允许有一个分区是活动的)或3个主分区+1个扩展分区(包含多个逻辑分区),扩展分区必须划分为逻辑分区才能使用,1个扩展分区可以划分多个逻辑分区。GPT分区表对分区数量没有限制,但在Windows系统上最多可以支持128个主分区。


传统的Legacy BIOS无法识别GPT分区表格式,所以也就没有LegacyBIOS+GPT的组合方式,也就是说传统Legacy BIOS引导系统的时候只能通过MBR来引导。MBR位于硬盘的0柱面、0磁头、1扇区,占用512个字节。MBR不属于任何一个操作系统,是所有系统公用的,它先于所有的操作系统被调入内存并发挥作用,然后才将控制权交给活动主分区内的操作系统。安装操作系统的时候安装程序会在MBR中写入引导程序,电脑开机以后MBR中的引导程序会自动在活动分区中搜寻相应的启动程序并执行:

More...


使用AmazeUI做了个ZblogPHP主题

ZblogASP有一个AmazeUI的主题,非常喜欢,可惜PHP版的Zblog没有这个主题,于是自己就做了一个。

两栏布局,灰色简洁风格,适合个人博客使用。响应式布局,自动适应手机、平板、桌面等各种尺寸的显示。

index_phone.png

More...


中国民航飞行员辞职现状分析

我在上一篇文章《中国民航飞行员辞职诉讼法律法规解读》中详细介绍了飞行员辞职再就业相关的法律法规。根据这些法律法规,从理论上讲飞行员通过司法诉讼辞职的道路是一片坦途。但是理想很丰满,现实却很骨感,近几年来飞行员通过司法诉讼辞职成功的案例非常少,特别是三大航,几乎没有一起成功的案例!这又是为什么?现在我就来讲讲辞职飞行员再就业的现实情况。

在飞行员再就业的三大手续里,体检关系和安保评价一般的法院判决书里都支持。就算法院判决不支持,也可以不依赖原公司通过其他途径来解决。原公司唯一能卡住飞行员再就业的只有“飞行员注册”。为了说明辞职飞行员在办理飞行员注册手续时所面临的一些问题,我这里举三个飞行员的栗子:

More...


中国民航飞行员辞职诉讼法律法规解读

文章开始之前,我先给大家讲讲古时候青楼女子和老鸨的那些事,算是做个普法教育。

老鸨对青楼女子的控制有两项收入,一项我们可以称之为营业性收人,也就是青楼女子在青楼接待客人的收入,一项是财产性收入,即出售青楼女子本身形成的收入,也就是青楼女子赎身的收入。在青楼女子进入青楼之初,老鸨像老师一样教习她各种技能,之后要求她们将这些技能应用于工作并获得相应报酬,而青楼女子如何才能赎身则由老鸨规定条件。老鸨在青楼女子赎身的时候,会以培养费为借口要一大笔钱,但事实上老鸨在青楼女子为其工作时,就已经收回了培养成本。尽管如此,旧社会的老鸨们其实还是很有契约精神的,只要你肯拿出赎身的银两,老鸨立马就会交出卖身契放人,而不会闹到衙门去打官司,一审二审拖你个两三年。

More...