如何将 shell 脚本添加为 Snap 提供的命令?

如何将 shell 脚本添加为 Snap 提供的命令?

假设我有一个基本的 shell 脚本 foo.sh:

#!/bin/sh
while [ 1 ]
do
    echo "looping"
    sleep 1
done

我想将其作为命令提出:/snap/bin/myapp.foo

我有 snapcraft.yaml:

apps:                                                                                                                                              
  foo:
    command: opt/foo/bin/foo.sh

parts:
  foo:
    source: .
    plugin: dump
    organize:
      foo.sh: opt/foo/bin/foo.sh

这会产生一个文件/snap/bin/myapp.foo,但它是指向 /usr/bin/snap 的链接。运行该命令时,我遇到了分段错误。

为此设置 snapcraft.yaml 的正确方法是什么?我想知道我是否必须打包sh到 Snap 中?或者 shell 脚本是否不适用于 snap?

答案1

好吧,有两件东西缺失了。

1) 在命令部分下,应使用 $SNAP 环境变量。您创建的所有部分将在运行时相对于该环境变量进行存储。

2) 不要直接调用 shell 脚本,而是指定解释器(本例中为“sh”)。如果没有这个,脚本就会失败。

apps:
  foo:
    command: sh $SNAP/opt/foo/bin/foo.sh

parts:
  foo:
    source: .
    plugin: dump
    organize:
            foo.sh: opt/foo/bin/foo.sh

附录 1:事实证明,对我的使用来说真正重要的因素是在 Ubuntu 18 中,Snap 与 Ubuntu 16 中的 libc 版本绑定。这导致 Snap 需要将 Ubuntu 18 的 libc6 吸收到我的 Snap 中,这反过来会与 bash 和 dash/sh 等产生冲突。

如果您尝试运行 shell 脚本并看到段错误,则可能与此有关。进程尝试调用 shell 脚本,读取顶部的“shebang”(“#!/bin/bash”),当它运行 /bin/bash 时,会发生 libc 冲突。

附录 2:对于父进程启动 shell 脚本的情况,请注意顶部的“shebang”语句可能无效。例如,“#!/bin/sh”将无法正确解析,因为实际路径将是“$SNAP/bin/sh”,它将解析为“/snap/project-name/project-revision/bin/sh”之类的内容。

为了解决这个问题,请确保将 PATH 环境传递给程序,并将 $SNAP 前缀到每个相关路径。然后调整父程序以使用解释器调用脚本,例如“bash child.sh”与“child.sh”。

相关内容