我注意到有时 python 脚本不是直接启动的,即/foo/bar.py
,而是从 shell 脚本启动,它除了/usr/bin/python -O /foo/bar.py $@
网络管理员就是这样的一个例子wicd
。/usr/bin/wicd-gtk
是一个 shell 脚本,它启动wicd-client.py
:
$ cat /usr/bin/wicd-gtk
exec /usr/bin/python -O /usr/share/wicd/gtk/wicd-client.py $@
这个额外步骤的目的是什么?
/usr/share/wicd/gtk/wicd-client.py
如果我直接启动(只要它是可执行的)会有什么区别?
答案1
(以下纯属猜测。)
您拥有的是 Wicd 的打包版本,并且软件包维护者已使用发行版打包的 Python 版本对其进行了测试。但是,它/usr/share/wicd/gtk/wicd-client.py
使用以下代码编写:
#!/usr/bin/env python
情况很可能与/usr/bin/env
不同,特别是如果您进行任何 Python 编程。打包者可能希望避免这种情况,只是为了减少由于 Wicd 在不同的 Python 版本下运行或使用不同版本的库而出现问题的可能性。python
/usr/bin/python
他们可能还想做其他准备工作。wicd-gtk
在 Ubuntu 14.04 上有这样的/usr/bin/wicd-gtk
:
#!/bin/sh
# check_firstrun()
if [ ! -d "$HOME/.wicd" ]; then
mkdir -p "$HOME/.wicd"
fi
# Make sure the user knows WHEREAREMYFILES ;-)
if [ -e "/var/lib/wicd/WHEREAREMYFILES" ] && [ ! -L "$HOME/.wicd/WHEREAREMYFILES" ]; then
ln -s "/var/lib/wicd/WHEREAREMYFILES" "$HOME/.wicd/WHEREAREMYFILES"
fi
exec /usr/bin/python -O /usr/share/wicd/gtk/wicd-client.py $@
答案2
您没有发布完整的脚本 - 该脚本在运行之前会执行其他操作wicd-client.py
。它首先确保某个目录和某个符号链接存在:
# check_firstrun() if [ ! -d "$HOME/.wicd" ]; then mkdir -p "$HOME/.wicd" fi # Make sure the user knows WHEREAREMYFILES ;-) if [ -e "/var/lib/wicd/WHEREAREMYFILES" ] && [ ! -L "$HOME/.wicd/WHEREAREMYFILES" ]; then ln -s "/var/lib/wicd/WHEREAREMYFILES" "$HOME/.wicd/WHEREAREMYFILES" fi
然后它使用该-O
选项运行Python,这会导致它优化字节码。我不知道这有什么用处。
包装器脚本也强制/usr/bin/python
使用,但/usr/share/wicd/gtk/wicd-client.py
以 开头#!/usr/bin/env python
,因此它会选择python
命令搜索路径中第一个出现的那个。在大多数系统上,这不会产生任何影响。
请注意,此脚本中有一个错误:$@
应该是"$@"
。如果任何参数包含空格或通配符,则包装器脚本将失败\[*?
。
/usr/share/wicd/gtk/wicd-client.py
只要~/.wicd
存在,您就可以安全地手动运行。不过,Debian 软件包并没有使其可执行;也许其他发行版也可以。