如何使用 bash 结构,如 'cd' 或 '&&' 或 '>' 重定向与 ddev exec?

How can I use bash constructs like 'cd' or '&&' or '>' redirection with ddev exec?

我正在尝试使用 ddev exec 在容器中使用 bash 做一些复杂的事情,但似乎无法让它工作。例如,ddev exec cd /var/tmp 会导致一条大错误消息

Failed to execute command [cd /var/tmp]: Failed to run docker-compose [-f /Users/rfay/workspace/d8git/.ddev/docker-compose.yaml exec -T web cd /var/tmp], err='exit status 126', stdout='OCI runtime exec failed: exec failed: container_linux.go:348: starting container process caused "exec: \"cd\": executable file not found in $PATH": unknown

并尝试使用“||”使用“>”的“&&”或shell重定向也不起作用。

编辑 2019-05-14:截至今天的 ddev 版本 v1.8.0,以下答案已过时,因为 ddev exec 和 exec 挂钩在 bash 上下文中执行。所以 ddev exec "ls | grep php" 现在可以工作,ddev exec "mysql db <somefile.sql" 可以工作,就像 exec: mysql <somefile.sql

这样的 exec 挂钩一样

ddev exec(和 config.yaml 中的 "exec" 挂钩)都执行实际命令,而不是在 shell 的上下文中执行。 "cd" 不是 Linux 命令,而是 shell 内置命令。而“&&”、“||”和“>”或“>>”也是 shell 结构。所以我们必须采取一些变通办法才能使它们正常工作。

但我们可以明确地使用 bash 让这些东西起作用:

ddev exec bash -c "cd /var/tmp && ls > /tmp/junk.txt"

在 post-start 挂钩中做同样的事情 config.yaml:

   hooks:
     post-start:
       - exec: bash -c "cd /var/tmp && ls > /tmp/junk.txt"

请注意,环境变量不会在 exec 语句之间持续存在,因为它们位于不同的 shells 中,因此如果您需要保持上下文以在一行中执行此操作,则最好。

另请注意,如果您想重定向 stdout/stderr,您 可以 在容器内(如上所述)或主机(重定向 ddev exec 输出)重定向像这样:

ddev exec bash -c "cd /var/tmp && ls" >/tmp/junk.txt

ddev exec 将来可能会在 bash 的上下文中执行命令以使其更加透明。