是否知道大多数shebang
实现都支持单个参数,所以如果您有类似
#!/usr/bin/env some-tool-accepting-yaml param1 param2
... (yaml body)
它现在将按预期工作,因为它将使用" param1 param2"来调用该工具。参数而不是将其分成两个参数。
似乎一个workaround练习是使用类似的东西:
#!/bin/sh
arbitrary_long_name==0 "exec" "/usr/bin/gawk" "--re-interval" "-f" "$0" "$@"
现在这种方法会因为第二行而使基于YAML的脚本无效,所以唯一可接受的解决方法是也是一个注释,从"#"开始。太
有没有办法绕过这个问题?
答案 0 :(得分:3)
不使用多语言脚本的一般解决方案
#!/bin/bash
# first argument to be split
if [[ $- != *f* ]]; then reset=1; fi
set -f
arg=( $1 )
shift
if [[ $reset = 1 ]]; then set +f; fi
# other arguments
arg+=("$@")
# launch command
exec "${arg[@]}"
#!/path/to/launcher.sh interpreter opts
答案 1 :(得分:0)
没有针对此问题的通用解决方案(除非您使用的是MacOSX,可以在shebang
行中传递多个参数),但是对于特定要求的组合,可以使用shell技巧,例如:>
#!/bin/sh
exec yamllint -f colored --no-warnings ${1:+-c ${1}} - <<...
---
(YAML document)
...
我们正在使用外壳程序的HERE-doc
功能和YAML文档结束标记...
来表示外壳程序输入的结束位置。请注意,这仅适用于可以接受来自STDIN的输入的命令。
如果some-tool
需要文件名作为输入参数,则可以(ab)使用bash
就地文件实现功能,其中命令的输出通过映射的文件描述符传递:>
#!/bin/bash
exec ansible-playbook --ask-become-pass ${1:+--extra-vars hostname=${1}} <(tail +3 ${0})
---
- hosts: all
gather_facts: false
become: true
vars_prompt:
- name: hostname
prompt: "Hostname"
private: no
tasks:
(YAML document)
我们正在传递tail
命令的输出,跳过文件的前三行通过/dev/fd/xx
文件描述符,ansible-playbook
将其视为普通可读文件。 / p>