我有一个简单的脚本:
#!/usr/bin/env ruby --verbose
# script.rb
puts "hi"
Run Code Online (Sandbox Code Playgroud)
在我的 OSX 机器上,它运行良好:
osx% ./script.rb
hi
Run Code Online (Sandbox Code Playgroud)
但是,在我的 linux 机器上,它会引发错误
linux% ./script.rb
/usr/bin/env: ruby --verbose: No such file or directory
Run Code Online (Sandbox Code Playgroud)
如果我手动运行 shebang 线,它工作正常
linux% /usr/bin/env ruby --verbose ./script.rb
hi
Run Code Online (Sandbox Code Playgroud)
但是如果我打包ruby --verbose
成一个参数,我可以复制错误env
linux% /usr/bin/env "ruby --verbose" ./script.rb
/usr/bin/env: ruby --verbose: No such file or directory
Run Code Online (Sandbox Code Playgroud)
所以我认为这是如何env
解释shebang线的重置的问题。我正在使用 GNU coreutils 8.4 env
:
linux% /usr/bin/env --version
env (GNU coreutils) 8.4
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL …
Run Code Online (Sandbox Code Playgroud) 命令env ls -al
在做什么?
我有一个 Linux 测试,有一个问题:“如何直接运行命令,而不是它的别名?”
我知道存在一些解决方案,例如在命令前加上一些特殊符号,但我忘记了。现在我知道了\
。(从这篇文章中阅读)。
但我也记得我在某处读到过,为了摆脱别名,我们可以在命令前加上env
. 我做到了,它似乎有效,但我的回答被认为是错误的。我读info
和man
上env
,但并没有理解太多。
env
在env <command>
没有任何论据的情况下,究竟在做什么env
?
输入/usr/bin/env sed -f
终端工作。
但如果将其用作shebang,
#!/usr/bin/env sed -f
s/a/b/
Run Code Online (Sandbox Code Playgroud)
脚本将无法执行:
/usr/bin/env: sed -f: No such file or directory
Run Code Online (Sandbox Code Playgroud)
我有点相信它与-f有关。但是如何解决这个问题呢?
假设我调用A=B command
和env A=B command
in bash
。是否存在两种调用之间可能存在差异的情况?
我尝试了以下但它似乎不起作用:
$ cat script.sh
#!/bin/env -i /bin/sh
/bin/env
$ script.sh
/bin/env: invalid option -- ' '
Try `/bin/env --help' for more information.
Run Code Online (Sandbox Code Playgroud) gawk 通常是在 /bin 还是 /usr/bin 中?我会去,#!/usr/bin/env gawk
但后来我不能使用参数。现在我正在使用#!/bin/gawk -f
. 脚本很长,包含很多单引号,并与标准输入一起使用。
GNU Awk 手册有部分 1.1.4 Executable awk Programs在它的示例中使用 #!/bin/awk 但接着说:
请注意,在许多系统上
awk
可能会发现 in/usr/bin
而不是 in/bin
。买者自负。
大多数人做什么?我读过sed 应该在 /bin 中标准化,而 perl 应该在 /usr/bin 中标准化(与 sed 链接相同的页面,但他们不会让我为这篇文章制作第三个链接)。awk/gawk 怎么样?有谁知道哪个更常见或更受欢迎?
在可执行文件中,您使用 shebang 指定环境:
#!/usr/bin/env ruby
# ruby code here
Run Code Online (Sandbox Code Playgroud)
但是如果你想指定多个可能的环境怎么办?例如,如果您安装了多个版本的 Ruby,您可能想要执行类似的操作
#!/path/to/better/ruby/version
#!/path/to/alternative/ruby/version
# ruby code here
Run Code Online (Sandbox Code Playgroud)
如何为单个可执行文件指定多个可能的环境?
我经常会看到脚本以#!/usr/bin/env interpreter_name
用于任何解释器的 shebang 行开头,理由是不同的系统可能具有它们需要的解释器,以便在不同的地方运行。例如,如果我假设python
已安装,/usr/bin/python
那么某些/opt/python
出于某种原因决定安装它的用户将无法轻松使用它。
但显而易见的问题是,是否有任何保证env
将安装在/usr/bin/env
(或就此而言任何特定的地方),或者这只是“移动问题”的一个案例?
这个稍微相关的问题有一条评论说这是一个坏主意,最好使用解释器的实际路径安装它并引用单个 unix 规范,但并没有真正解决这个问题。
我正在尝试env
用于为子进程设置环境变量(从另一个来源读取,例如文件)。本质上,我正在尝试以下操作:
env VALUE=thisisatest ./somescript.sh
Run Code Online (Sandbox Code Playgroud)
例如,如果somescript.sh
是:
echo $VALUE
Run Code Online (Sandbox Code Playgroud)
然后这将按thisisatest
预期打印。但我想从文件中加载变量。我已经到了这一点:
env $(cat .vars | xargs -d '\n') ./somescript.sh
Run Code Online (Sandbox Code Playgroud)
但是,当任何变量包含空格(并且引号不能按预期工作)时,我就会遇到麻烦。例如:
env $(echo 'VALUE="this is a test"' | xargs -d '\n') ./somescript.sh
Run Code Online (Sandbox Code Playgroud)
会出错
env: is: No such file or directory
Run Code Online (Sandbox Code Playgroud)
并尝试:
env $(echo 'VALUE="thisisatest"' | xargs -d '\n') ./somescript.sh
Run Code Online (Sandbox Code Playgroud)
会给我意想不到的:
"thisisatest"
Run Code Online (Sandbox Code Playgroud)
我认为这会正常工作,因为运行env VALUE="thisisatest" ./somescript.sh
打印它没有引号。
从错误中,我发现由于某种原因 env 不理解引号意味着后面的值应该是一个字符串。但是,我不确定如何以正确解释引号的方式插入这些变量。
任何人都可以提供有关如何完成此操作的任何提示吗?
谢谢!
Solaris / sh
我在一个文件中定义了一些函数,这些函数通过加载
. ./some_file.sh
Run Code Online (Sandbox Code Playgroud)
当我开始一个子shell时
sh
Run Code Online (Sandbox Code Playgroud)
我所有的函数定义都丢失了,但是当我这样做时
env
Run Code Online (Sandbox Code Playgroud)
我确实看到了源代码,有没有一种简单的方法可以让它们在我的子 shell 中运行?
env ×10
bash ×3
scripting ×3
executable ×2
shell ×2
awk ×1
command ×1
command-line ×1
function ×1
linux ×1
ruby ×1
sed ×1
shebang ×1
shell-script ×1
subshell ×1