如何使用 scl 命令作为脚本 shebang?

How to use scl command as a script shebang?

如果我想 运行 软件集合下的特定命令(带参数),我可以使用这个命令:

scl enable python27 "ls /tmp"

但是,如果我尝试制作一个 shell 脚本,该脚本具有与其 shebang 行相似的命令,我会收到错误消息:

$ cat myscript
#!/usr/bin/scl enable python27 "ls /tmp"
echo hello

$ ./myscript
Unable to open /etc/scl/prefixes/"ls!

我做错了什么?

she-bang 命令中参数的解析并未真正定义。来自 man execve:

The semantics of the optional-arg argument of an interpreter script vary across implementations. 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. However, behavior differs on some other systems. Some systems use the first white space to terminate optional-arg. On some systems, an interpreter script can have multiple arguments, and white spaces in optional-arg are used to delimit the arguments.

无论如何,不​​支持基于引用sis 的参数拆分。所以当你写:

#!/usr/bin/scl enable python27 "ls /tmp"

很可能调用的是(使用bash表示法):

'/usr/bin/scl' 'enable' 'python27' '"ls' '/tmp"'

这可能就是它试图在 /etc/scl/prefixes/"ls

打开 "ls 文件的原因

但 shebang 的计算结果很可能是:

'/usr/bin/scl' 'enable python27 "ls /tmp"'

这会失败,因为它无法找到名为 enable python27 "ls /tmp" 的命令供 scl 执行。

您可以使用一些解决方法。

您可以通过 scl 调用您的脚本:

$ cat myscript
#!/bin/bash
echo hello

$ scl enable python27 ./myscript
hello

您也可以使用 heredoc 表示法,但这可能会导致一些微妙的问题。我个人避免这样做:

$ cat ./myscript
#!/bin/bash
scl enable python27 -- <<EOF
echo hi
echo $X_SCLS
EOF

$ bash -x myscript 
+ scl enable python27 --
hi
python27

您已经可以看出其中一个陷阱:我必须编写 $X_SCLS 来访问环境变量,而不仅仅是 $X_SCL.

编辑:另一种选择是两个有两个脚本。一个有实际代码,第二个只是 scl enable python27 $FIRST_SCRIPT。这样您就不必记住手动输入 scl ...

您应该尝试使用 -- 而不是用引号括起您的命令。

scl enable python27 -- ls /tmp

我能够制作一个 python 脚本,该脚本使用 rh-python35 集合和这个 shebang:

#!/usr/bin/scl enable rh-python35 -- python

import sys
print(sys.version)