- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
假设我们有一个程序/包,它带有自己的解释器和一组应该在执行时调用它的脚本(使用 shebang)。
假设我们希望保持它的可移植性,因此即使只是简单地复制到不同的位置(不同的机器)而不调用设置/安装或修改环境 (PATH),它仍能正常运行。不应为这些脚本混入系统解释器。
给定的约束排除了两种已知的方法,例如使用绝对路径的 shebang:
#!/usr/bin/python
并在环境中搜索
#!/usr/bin/env python
单独的发射器看起来很难看,是 Not Acceptable 。
我找到了 shebang 限制的一个很好的总结,它描述了为什么 shebang 中的相对路径是无用的,并且不能有一个以上的参数给解释器:http://www.in-ulm.de/~mascheck/various/shebang/
而且我还找到了practical solutions对于大多数具有“多行 shebang”技巧的语言。它允许编写这样的脚本:
#!/bin/sh
"exec" "`dirname $0`/python2.7" "$0" "$@"
print copyright
但有时,我们不想使用这种方法扩展/修补依赖于 shebang 的现有脚本,以及解释器的绝对路径。例如。 Python 的 setup.py 支持 --executable
选项,它基本上允许为其生成的脚本指定 shebang 内容:
python setup.py build --executable=/opt/local/bin/python
因此,特别是,可以为 --executable=
指定什么以实现所需的可移植性?或者换句话说,因为我不想让这个问题对 Python 太具体...
如何编写一个 shebang,它指定一个解释器,其路径相对于正在执行的脚本的位置?
最佳答案
直接写在 shebang 中的相对路径是相对于当前工作目录的,所以像 #!../bin/python2.7
这样的东西对任何其他工作目录都不起作用,除了少数.
既然操作系统不支持它,为什么不使用外部程序,比如使用env
来查找PATH
。但我知道没有专门的程序可以根据参数计算相对路径并执行结果命令……除了 shell 本身和其他脚本引擎。
但是尝试在像这样的 shell 脚本中计算路径
#!/bin/sh -c '`dirname $0`/python2.7 $0'
不起作用,因为在 Linux 上 shebang 仅受一个参数的限制。这建议我寻找接受脚本作为命令行第一个参数并能够执行新进程的脚本引擎:
#!/usr/bin/awk BEGIN{a=ARGV[1];sub(/[a-z_.]+$/,"python2.7",a);system(a"\t"ARGV[1])}
#!/usr/bin/perl -e$_=$ARGV[0];exec(s/\w+$/python2.7/r,$_)
21 年 1 月 11 日更新:
env
实用程序:$ env --version | grep env
env (GNU coreutils) 8.30
$ env --help
Usage: env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]
Set each NAME to VALUE in the environment and run COMMAND.
Mandatory arguments to long options are mandatory for short options too.
-i, --ignore-environment start with an empty environment
-0, --null end each output line with NUL, not newline
-u, --unset=NAME remove variable from the environment
-C, --chdir=DIR change working directory to DIR
-S, --split-string=S process and split S into separate arguments;
used to pass multiple arguments on shebang lines
因此,将 -S
传递给 env 即可完成工作
关于python - 相对 shebang : How to write an executable script running portable interpreter which comes with it,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33225082/
我想在其他“已批准”域上放一个指向我网站的链接。当他们单击链接时,它会转到一个页面,该页面会检查引荐来源网址 ($_SERVER['HTTP_REFERRER']) 以确保它们来自已获准拥有我的链接的
我用这一行创建一个 defaultdict 并使用列表作为值对其进行初始化。 page_by_due_date = defaultdict(list) due_pages_list = [] for
我有一个使用大量内存的 Java 程序。我使用 jmap -histo:live 来追踪正在使用所有内存的对象。只有几种类型占用了大部分内存,其中超过 1M,但我无法判断引用的来源来自。 有什么方法可
我正在尝试使用 Android 电话管理器结束调用(新的调用筛选 API 不适合我)。我在网上找到了很多例子,都与我下面的代码非常相似。它编译得很好,但我在运行时遇到了 ClassCastExcept
我有一个用 Visual Studio 编写的小型 C++ dll(当然)。在解决方案代码中,我有一个仅包含版本信息的资源文件。 奇怪的是,当我将已编译的 dll 分片到 Visual Studio
所以我明白了什么是装箱和拆箱。它什么时候出现在现实世界的代码中,或者在什么例子中它是一个问题?我无法想象做这样的事情: int i = 123; object o = i; //
我们的 winforms 应用程序与 MS Word 交互,我们在生成文档并希望在应用程序前面的 Word 中显示它时运行此代码: [setup w as a Word interop object]
我最近已从Mac开发环境切换到Windows开发环境。我广泛用于Chrles代理来捕获网络流量,请求和响应详细信息。现在,我已经在Windows 8中安装了Charles Proxy 3.7版。但是,
假设我有一个带有电子邮件表单元素的表单;例如,当我在此字段中输入 1 个字母并按“确定”时,我会在工具提示中收到一条用我的语言(法语)显示的消息:“Veuillez saisir une adress
解释问题: 我现在已经尝试让 firebase_messaging 工作近一周。 我成功设置了一个旧版 Xcode APNS 应用程序,该应用程序在生成所有新证书等后工作。 但是使用 firebase
我想知道域实现的常见做法是什么。首先设计需要持久性或数据库模式的业务对象,然后从实体关系图(然后是 ORM poco*)生成它? 我要开始一个解决方案,但我想知道哪个是最优选的“模式”。 (*由 NH
我看到一个用 Node.js 构建的应用程序,但我不明白 describe 和 it 这两个词如何可用? 在浏览器控制台中,它 是一个函数,describe 抛出一个ReferenceError。 我
我看到一个用 Node.js 构建的应用程序,但我不明白 describe 和 it 这两个词如何可用? 在浏览器控制台中,它 是一个函数,describe 抛出一个ReferenceError。 我
所以我正在尝试学习 django 并遵循本教程:https://docs.djangoproject.com/en/1.10/intro/tutorial01/ 按照教程制作民意调查应用程序后,当我回
故事 我已经在 OpenGL 中编码大约一年了(在相同的硬件上),我最近才得到像上图中那样的工件。它们在短时间内(几分钟)连续运行我的程序后出现,并出现在任何地方:从写字板(见图片)到我的桌面和任务栏
我对下面名为test(第 3 行)的函数的使用感到好奇: var pattern = /[1-9][1-9]{5}/; var str = 'this is 248760!'; alert(patte
当我正在使用的 CodeIgniter 应用程序尝试特定的 UPDATE 操作时,我收到一个非常奇怪的数据库错误。 Active Record 调用是: $this->db->update('eval
我的目标是显示一张图片并将其慢慢带到前台(并在主要时间内延长)。我希望当我在 div/img 上检测到事件 onmouseover 时可以完成此操作。 目前,我使用隐藏属性,但我不喜欢它,因为它就像:
我有一个页面,我通过查询字符串发送了一个参数。 如果我使用 Request.QueryString["Format"] 检索它,我会遇到类型 'CD\DVD' 的问题。它作为“CD\\DVD”返回。重
我在 ListView 中遇到了一个奇怪的行为,只有一个 ListView,我的应用程序中有很多 ListView,但只有在这种情况下才会发生。 我会试着解释一下,当我滚动到底部时,好吧,滚动会停止。
我是一名优秀的程序员,十分优秀!