【问题标题】:Exec in Bash /bin/kill not found在 Bash /bin/kill 中找不到执行
【发布时间】:2018-09-25 13:45:19
【问题描述】:

我正在迁移一个刚刚使用 sh 到 bash 的脚本,该脚本最初看起来像这样:

 #!/bin/sh
 ... a bunch of setup ...
 exec "$@"

当我通过以下方式运行脚本时:

./my_script kill -l

我得到一个可用信号列表:

HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT
CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH POLL PWR SYS

但是,我想使用 bash 信号名称,所以我想我可以简单地:

#!/bin/bash

exec bash -l "$@"

现在的问题是kill不被识别:

/bin/kill: /bin/kill: cannot execute binary file

真的,我的脚本只是另一个进程的包装,我需要确保可以向它发送kill -SIGTERM 的信号。

【问题讨论】:

  • 不确定是否发现问题。当我创建一个只有 bash 的 shebang 和唯一行的脚本时: exec "$@"...../my_script kill -l 工作得很好,我得到了预期的输出。

标签: bash shell sh exec


【解决方案1】:

您需要添加-c 选项。否则(请参阅bash 手册页的 ARGUMENTS 部分)“...第一个参数假定为包含 shell 命令的文件的名称。”

即:

exec bash -lc "$*"

【讨论】:

  • 你可能想要$*这里;否则,exec bash -lc kill -l 会将-l 视为bash 命令中$0 的值,而kill 将不会收到任何参数。 (当然,$* 可能由于不同的原因出错,这就是编写这种包装器很脆弱的原因。)
【解决方案2】:

你告诉 bash 运行一个文件,它期望是一个 bash 脚本,但结果却是一个二进制可执行文件。

而不是这个:

#!/bin/bash

exec bash -l "$@"

使用这个:

#!/bin/bash

exec bash -c "$1"

是否有特定原因需要选项-l 将 bash 作为“登录”shell 运行?如果不只是使用选项-c 来运行字符串参数。

更新为使用$1 而不是$@,因为它更适合@chepner 评论的字符串参数。

这还要求您将参数作为字符串发送,而不是对二进制文件的引用。

而不是这个:

./my_script kill -l

这样做:

./my_script "kill -l"

【讨论】:

  • 如果你传递一个字符串,你绝对应该使用$*(或者更好,$1)而不是$@,因为你真的不希望多个参数传递给@987654332 @,只是 -c 选项的一个参数。
  • 我实际上是在向./myscript ./my_other_scipt 发送另一个脚本——这会改变你对使用$1 的看法吗?
  • @Anthony 当然在这种情况下使用$1。不要尝试使用任何您不希望调用者可能错误(或故意)传递的额外参数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-02
  • 2018-09-15
  • 2020-12-19
  • 2016-02-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多