有没有办法动态选择正在执行脚本的解释器?我有一个在两个不同系统上运行的脚本,我想使用的解释器位于两个系统上的不同位置。我最终不得不在每次切换时更改 hashbang 行。我想做一些与此逻辑等效的事情(我意识到这种确切的构造是不可能的):
if running on system A:
#!/path/to/python/on/systemA
elif running on system B:
#!/path/on/systemB
#Rest of script goes here
Run Code Online (Sandbox Code Playgroud)
或者更好的是这样,以便它尝试使用第一个解释器,如果没有找到,则使用第二个解释器:
try:
#!/path/to/python/on/systemA
except:
#!path/on/systemB
#Rest of script goes here
Run Code Online (Sandbox Code Playgroud)
显然,我可以
根据我所在的位置/path/to/python/on/systemA myscript.py
或
/path/on/systemB myscript.py
根据我所在的位置来执行它
,但我实际上有一个启动的包装脚本myscript.py
,所以我想以编程方式而不是手动指定 python 解释器的路径。
我一直认为 shell 会解析整个脚本,构建一个 AST,然后从内存中执行该 AST。但是,我刚刚阅读了 Stéphane Chazelas 的评论,并测试了执行此脚本 edit-while-executing.sh:
#!/bin/bash
echo start
sleep 10
Run Code Online (Sandbox Code Playgroud)
然后在它睡觉的时候运行:
$ echo "echo end" >> edit-while-executing.sh
Run Code Online (Sandbox Code Playgroud)
它的作用是让它在最后打印“结束”。
但是,当尝试修改它时:
#!/bin/bash
while true; do
echo yes
done
Run Code Online (Sandbox Code Playgroud)
通过做:
$ printf "%s" "no " | dd of=edit-while-executing.sh conv=notrunc seek=35 bs=1
Run Code Online (Sandbox Code Playgroud)
它不起作用,并继续打印“是”。
我还想知道其他非 shell 解释器是否也这样工作,并尝试使用 python 执行与第一个脚本等效的操作,但没有奏效。不过,也许 python 不再是解释器,它更像是一个 JIT 编译器。
所以重申我的问题,这是一种普遍存在于 shell 并仅限于它们的行为,还是也存在于其他解释器中(那些不被视为 shell 的)?另外这是如何工作的,以便我可以进行第一次修改而不是第二次修改?
我所有的 Python 和 Perl 脚本都不是通过 shebang 进行迭代的。绝不。但是当我显式调用二进制文件时,它们按预期工作。
我仔细检查了我的 Perl 和 Python 安装,这太奇怪了:它们在正常主机上的目标系统 chroot 中以shebang方式执行运行得非常好,但在实际运行的系统中却没有。
我在一个自制的 Linux 系统上工作,该系统在该问题出现之前运行良好。自己看:
对“xscreensaver-text”Perl 程序的测试,一次通过shebang,然后使用CLI 上的解释器:
$ LC_ALL=C LANG=C /usr/bin/xscreensaver-text
/usr/bin/xscreensaver-text: line 23: require: command not found
/usr/bin/xscreensaver-text: line 25: use: command not found
/usr/bin/xscreensaver-text: line 29: BEGIN: command not found
/usr/bin/xscreensaver-text: line 31: use: command not found
/usr/bin/xscreensaver-text: line 32: syntax error near unexpected token `('
/usr/bin/xscreensaver-text: line 32: `use POSIX qw(strftime);'
$ LC_ALL=C LANG=C perl /usr/bin/xscreensaver-text
poopy
Linux 3.11.1
Sat Oct 5 23:07:33 2013 …
Run Code Online (Sandbox Code Playgroud) 在具有固定(较低)CPU 时钟速度(例如,runat 400mhz ./my-program --argument-of="my program"
为了获得该时钟速度)的 Linux 环境中运行特定程序对我来说非常有用。
我需要它来在我的程序的每个汇编指令之间产生延迟,如果延迟不准确(比如说,如果它取决于操作系统调度程序,因为它几乎肯定会),它不会杀死我。
目标是在学校编程不太繁重的应用程序时使算法效率非常明确(拥有 3GHz CPU 使得很难注意到运行时间很短并且可以真正优化的缓慢算法)。此外,它可能有助于实时发现竞争条件。
你知道任何这样的工具吗?有没有我可以破解的解释器来实现这一目标?gdb 能以相对简单的方式帮助我吗?我认为这是我所知道的最接近控制 Linux 程序执行的方法。
在 CPU 上限的 VM 中运行空洞系统可能是另一种选择,因为它给我提供了一种错觉——一个较低速度的 CPU——但是最好运行单个程序。
我正在编写可在多个操作系统上使用的期望脚本,但问题是
我不能使用#!/usr/bin/expect
evreywhere 所以我试着做
#!`which expect`
Run Code Online (Sandbox Code Playgroud)
在顶部,但失败了
[sesiv@itseelm-lx4151 ~]$ ./sendcommand
-bash: ./sendcommand: `which: bad interpreter: No such file or directory
Run Code Online (Sandbox Code Playgroud)
对此的任何解决方案。
如果当前用户对文件只有执行 (--x) 权限,解释器(由#!/path/to/interpreter
文件开头指定)在哪个用户下运行?
它不可能是当前用户,因为他没有读取文件的权限。它不能是 root,因为这样解释器中包含的任意代码将获得 root 访问权限。
那么,解释器进程作为哪个用户运行?
编辑:我认为我的问题假设该文件已经被读取到足以知道它指定了哪个解释器,而实际上它不会走那么远。解释执行目标文件的命令的当前 shell(通常是 b/a/sh)会尝试读取它,但会失败。
我了解到这个命令:
echo -e "\a"
Run Code Online (Sandbox Code Playgroud)
在本地系统上触发蜂鸣声,而此命令:
echo -e "\a" >/dev/console
Run Code Online (Sandbox Code Playgroud)
在远程系统上触发蜂鸣声。
为什么是这样?什么是>/dev/console
部分在做什么?
为什么echo -e "\a"
在远程机器上执行会在本地而不是远程触发哔声?
为什么“echo” - 命令不喜欢 sudo ?
是否有类似 OSI 层的方案?请向我提供一些外部文件。
我对将 stdout/stderr 重定向到文件只有一个基本的了解,但问题更可能是指“Gnu/Linux/Kernel”是如何设计的,以便重新重定向到
“ > /dev/console” 用于解决远程蜂鸣声。
遥控器是否echo "Hello World"
需要重定向到 /dev/console ?
shebang 标头必须始终与解释器的安装目录匹配吗?如果是这样,那么为什么既#!/usr/bin/python
和#!/usr/local/bin/python
我的工作?
我尝试将以下两个命令直接复制粘贴到终端中,然后执行它们:
read -s x
read -s y
Run Code Online (Sandbox Code Playgroud)
当前输出是空提示,但期望输出是第一次read
执行,然后是第二次read
执行。
我可以通过以下方式克服这个问题:
read -s x &&
read -s y
Run Code Online (Sandbox Code Playgroud)
但;
为什么不能一次执行两个或多个读取命令(没有一些分离语法)?
interpreter ×10
shebang ×5
executable ×3
linux ×3
shell-script ×3
shell ×2
bash ×1
exec ×1
gdb ×1
kernel ×1
permissions ×1
process ×1
profiling ×1
python ×1
read ×1
remote ×1
scheme ×1
scripting ×1
xml ×1