文章

以python为例,如何系统级的使用脚本

由于工作性质,在公司一般使用windows办公编程。但是我在家里写各种小工具、玩具的时候又是使用macos+linux这个技术栈,因此我一般使用python作为shellbatcommand的替代品。客观上来看,以上的三种脚本无论是易用性还是扩展性都远没有python高。这一点有做过各种持续集成的工具的朋友们应该都深有感触。

但是这种非原生的脚本毕竟和亲儿子还是有一定差距的,因此需要我们额外花费时间做一些配置。

如何使脚本双击即运行

相信我,你一定不会满足于在文件夹中右键点击打开terminal,并输入 python3 xxxx来打开脚本。

windows

右键任何python文件选择打开方式,将默认打开方式更换为python。环境变量中添加 .py为可执行文件,之后即可双击打开脚本。

mac

确保有安装单独的python(不要折腾系统原生的python3了,折腾坏了就不好修了)。确认python的地址并确定所有的python文件以#!加上你的python地址开头。例如你如果希望使用原生的python3打开,那就是以下面的注释开头。

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

随后执行chmod 777 xxx.py,对文件赋予执行权限。

此时确保 ./xxx.py使可以正常打开python文件的。

之后将.py的默认打开方式选择为 终端.app ,即可双击打开程序。

明确脚本路径

当你在命令行打开程序的时候,程序的当前路径只有三个可能

  • 执行路径
  • 程序的快捷方式、链接路径
  • 程序的实际路径、硬连接路径

当我们的程序以相对路径的方式获取配置等文件时,我们的涉及预期往往是使运行路径为第三种。那么我们需要先获取程序的路径。

python中常用的获取当前路径的函数有

os.getcwd

获得针对于当前执行路径的绝对路径。

sys.argv[0], os.path.abspath(\_\_FILE\_\_)

这两者比较相似,前者获得实际脚本的相对于当前执行路径的相对路径(实际上是python ./xxx/xxx.py里面的那个./xxx/xxx.ppy)。后者则是获得当前脚本的绝对路径。

但是这两者都无法正确的对软连接做出反应,返回的是软链接的路径。

os.path.realpath(\_\_FILE\_\_)

这个与path.abspath(\_\_FILE\_\_)比较类似,但是对于软链接会展示出正确的绝对路径。

因此版本答案就是

import os
os.chdir(os.path.dirname(os.path.realpath(__file__)))

如果你的程序是类似于lnls这种作用于当前执行路径或者不需要相对路径的文件的程序,那么完全可以不做处理。

如何在命令行快速调用脚本

如何调用

首先我们需要明确,只有在PATH中的文件才能在命令行里被不加路径的执行。这点在macwin中都是一样的。

maclinux在开头加上#!标识这是个可执行的脚本。而在win中,可以通过将.py后缀加入PATHEXT来,标识这是个可执行的脚本,同时与mac不同的是,win在将.py后缀加入PATHEXT后,可以实现免缀执行.py文件。`

  1. 创建一个文件夹
  2. 将这个文件夹加入PATH
    • mac推荐在用户配置.profile,或者.zprofile加入
    • win推荐环境变量配置里加入用户环境变量配置,并在系统的环境变量PATHEXT中加入.py

此时,一个名为xyz.py的程序应该可以通过xyzwindows中执行,或者通过 xyz.pymacos 中执行

选择正确的链接方式

一般我们不推荐将脚本直接丢进上文所说的文件夹。一方面会丢失版本控制,另一方面则会丢失相对路径。那么我们只有三种选择方案。

快捷方式、替身

这个玩意和我们所理解的链接完全是不一样的东西,本质上是一个可以被操作系统理解的文件。python等程序一定是无法理解的因此首先排除。

硬连接

win使用 mklink /H 创建

mac使用 ln 创建

缺点上面说了,难以确认真实路径。此外还有难以删除原文件的缺点。本质上是一个文件系统层的文件接口。指向真实的数据。

符号链接、软链接

win使用 mklink 创建

mac使用 ln -s 创建

没有啥缺点,因此建议选择这个。本质上是在文件系统层不是一个文件。默认推荐使用这个方式,除非你的脚本需要保证多处部署都能同步更改并隔离配置,那应该选择硬连接。

mac中需要注意软链接加入path后,立刻就可以直接执行,但是需要重启终端后才能使shell的补全对于新的命令生效。

windows中需要注意,软链接放入path后,如果不以可以执行的后缀作为后缀,是不能触发补全,且执行时会打开一个新的窗口。

misc

  • 需要注意winMaclinux的路径分隔符都有差异,因此最好选择path库处理路径或者统一使用./

最终版本

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
os.chdir(os.path.dirname(os.path.realpath(__file__)))
License:  CC BY 4.0