简体   繁体   English

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM