【问题标题】:Problems with exec "$@" in sh filesh 文件中 exec "$@" 的问题
【发布时间】:2021-12-09 05:06:45
【问题描述】:

我正在使用 sh 文件从 jupyterhub_config.py 文件中启动一些其他命令,它基本上为用户重新创建了一个 pod。

问题似乎在 sh 文件中,据我所知,我已经重构得最好。

echo "Executing the command: $@" 

exec "$@" & tail -f /var/log/logShell/logInShell.log

echo "External user startup script finished"

预期的行为是传递给“$@”的命令被执行,然后 logInShell.log 中的日志显示在 shell 中。但是,尽管文件有几行,但日志永远不会显示在 shell 中。

根据我的阅读,运行 exec 将替换子进程,这让我认为它也替换了 shell,这就是为什么在当前 shell 中永远看不到 tail 的结果。

Pod 运行后,我可以看到使用 ps -A 运行的 tail 命令。但是,日志根本不会进入 shell。有谁知道在当前进程或 shell 中获取 run tail 的正确方法是什么?。

【问题讨论】:

  • exec "$@" & 真的没有意义。 exec 替换当前进程,从而终止启动它的 shell。您不能在后台执行此操作,一旦完成,shell 将不再运行,因此您的最后一个 echo 永远不会被访问。你可以(exec "$@") &,但它和"$@" &一样,所以我不知道为什么有人会打扰。
  • 如果你想启动一个后台进程,只需使用"$@" & -- 省略exec
  • tail 也可能在创建日志文件之前启动。此外,tail -f 永远不会结束。
  • @UlrichEckhardt。 ...好点子;扩展了我的答案,展示了如何使用 GNU tail 解决这个问题。
  • exec ... & 首先分叉,然后 在分叉的 shell 中执行 exec。这是一个微优化,它会保留一个额外的 shell 进程,在预期的命令完成后不会使用它,而且我相信 bash 已经使用 exec 如果它看到它唯一的命令,那么它可能不是必需的是一个简单的可执行文件。

标签: python shell unix kubernetes sh


【解决方案1】:

省略 exec 关键字。您可能还想监视您包装的主程序何时退出,并在发生这种情况时关闭tail

#!/bin/sh

# warning: this is not actually echoing the same thing as the command you're running
echo "Executing the command: $@" 

# --follow=name --retry makes tail behave right even if the log is only created
# after tail's startup is complete; requires GNU extensions
"$@" & main_pid=$!
tail --follow=name --retry /var/log/logShell/logInShell.log & tail_pid=$!

wait "$main_pid"; main_rc=$?
echo "External user startup script finished"
kill "$tail_pid"
exit "$main_rc"

现在,关于为什么echo "Arguments are: $@" 积极误导/比无用更糟糕:

考虑./yourscript "first word" "*" "last word"——first wordlast word 周围的引号对于正确理解命令行至关重要; * 周围的引号相同。

但是,echo "Arguments are: $@" 运行 echo "Arguments are: first word" "*" "last word" -- 写入输出 Arguments are: first word * last word完全破坏原始命令中引号所在位置的记录

如果您的 shell 是 bash、zsh 或足够现代的 ksh,则这是一个非致命问题:您可以使用:而不是 echo "Arguments are: $@"

# bash only
printf -v args_str '%q ' "$@"
echo "Arguments are: $args_str"

...或者,使用 bash 5.0 或更高版本:

echo "Arguments are: ${*@Q}

...但是对于基线 POSIX sh,如果您想消除歧义,最好的选择可能是在第二行打印每个参数:

echo "Arguments are:"
printf ' - %s\n' "$@"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-06
    • 2015-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多