[英]How to use scl command as a script shebang?
If I want to run a specific command (with arguments) under Software Collections, I can use this command:如果我想在软件 Collections 下运行一个特定的命令(带参数),我可以使用这个命令:
scl enable python27 "ls /tmp"
However, if I try to make a shell script that has a similar command as its shebang line, I get errors:但是,如果我尝试制作一个 shell 脚本,该脚本具有与其 shebang 行类似的命令,我会收到错误消息:
$ cat myscript
#!/usr/bin/scl enable python27 "ls /tmp"
echo hello
$ ./myscript
Unable to open /etc/scl/prefixes/"ls!
What am I doing wrong?我究竟做错了什么?
The parsing of arguments in the she-bang command is not really defined. she-bang命令中对arguments的解析并没有真正定义。 From
man execve
:从
man execve
:
The semantics of the optional-arg argument of an interpreter script vary across implementations.
解释器脚本的 optional-arg 参数的语义因实现而异。 On Linux, the entire string following the interpreter name is passed as a single argument to the interpreter, and this string can include white space.
在 Linux 上,解释器名称后面的整个字符串作为单个参数传递给解释器,并且该字符串可以包含空格。 However, behavior differs on some other systems.
但是,在其他一些系统上的行为有所不同。 Some systems use the first white space to terminate optional-arg.
一些系统使用第一个空格来终止 optional-arg。 On some systems, an interpreter script can have multiple arguments, and white spaces in optional-arg are used to delimit the arguments.
在某些系统上,一个解释器脚本可以有多个 arguments,并且 optional-arg 中的空格用于分隔 arguments。
No matter what, argument splitting based on quote sis not supported.无论如何,不支持基于引号 sis 的参数拆分。 So when you write:
所以当你写:
#!/usr/bin/scl enable python27 "ls /tmp"
It's very possible that what gets invoked is (using bash notation):很可能被调用的是(使用 bash 表示法):
'/usr/bin/scl' 'enable' 'python27' '"ls' '/tmp"'
This is probably why it tries to open the "ls
file at /etc/scl/prefixes/"ls
这可能就是为什么它试图在
/etc/scl/prefixes/"ls
中打开"ls
文件”的原因
But it is just as likely that the shebang evaluates to:但是,shebang 评估为:
'/usr/bin/scl' 'enable python27 "ls /tmp"'
And that would fail since it wont be able to find a command named enable python27 "ls /tmp"
for scl to execute.这将失败,因为它无法找到一个名为
enable python27 "ls /tmp"
的命令来执行 scl。
There's a few workarounds you can use.您可以使用一些解决方法。
You can call your script via scl:您可以通过 scl 调用您的脚本:
$ cat myscript
#!/bin/bash
echo hello
$ scl enable python27 ./myscript
hello
You can also use the heredoc notation, but it might lead to subtle issues.您也可以使用heredoc表示法,但这可能会导致一些微妙的问题。 I personally avoid this:
我个人避免这种情况:
$ cat ./myscript
#!/bin/bash
scl enable python27 -- <<EOF
echo hi
echo \$X_SCLS
EOF
$ bash -x myscript
+ scl enable python27 --
hi
python27
You can see one of the gotcha's already: I had to write \$X_SCLS
to access the environment variable instead of just $X_SCL
.您已经可以看到其中一个问题:我必须编写
\$X_SCLS
来访问环境变量,而不仅仅是$X_SCL
。
Edit: Another option is two have two scripts.编辑:另一个选项是两个有两个脚本。 One that has the actual code, and the second that simply does
scl enable python27 $FIRST_SCRIPT
.一个具有实际代码,第二个只是
scl enable python27 $FIRST_SCRIPT
。 Then you wont have to remember to enter scl...
manually.然后你就不必记得手动输入
scl...
了。
You should try using --
instead of surrounding your command with quotes.您应该尝试使用
--
而不是用引号将您的命令括起来。
scl enable python27 -- ls /tmp
I was able to make a python script that uses the rh-python35 collection with this shebang:我能够制作一个 python 脚本,该脚本使用 rh-python35 集合和这个 shebang:
#!/usr/bin/scl enable rh-python35 -- python
import sys
print(sys.version)
The software collections documentation may also be helpful.软件 collections 文档也可能有帮助。 In particular you can try
特别是你可以试试
cat myscript.sh | scl enable python27 -
As well as permanently enabling a software collection以及永久启用软件集合
source scl_source enable python27
./myscript.sh
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.