因此,我希望能够让Python完成这些繁重的工作,然后在我的shell脚本中获取这些简化和净化后的值,而无需进一步担心用户指定的参数。
举个具体的例子,在我工作的许多shell脚本中,它们已经被定义为按照特定顺序接受它们的参数。 您可以调用
start_server.sh --server myserver --port 80
,但start_server.sh --port 80 --server myserver
会失败,并提示You must specify a server to start.
- 这使得解析代码更简单,但几乎没有直观性。因此,第一步的解决方案可以是让Python接收参数,对它们进行排序(保持它们旁边的参数),然后返回已排序的参数。因此,shell脚本仍然需要执行一些解析和净化操作,但用户可以输入比shell脚本本身接受的更任意的内容,例如:
# script.sh -o -aR --dir /tmp/test --verbose
。#!/bin/bash
args=$(order.py "$@")
# args is set to "-a --dir /tmp/test -o -R --verbose"
# simpler processing now that we can guarantee the order of parameters
这里有一些明显的限制,特别是parse.py
无法区分带参数的最终选项和索引参数的开始,但这似乎并不太糟糕。
所以我的问题是:1)是否存在现有的(最好是Python)实用程序,可以通过比bash更强大的方式进行CLI解析,然后在经过净化后由我的bash脚本的其余部分访问,或者2)是否有人做过这个?是否存在问题、陷阱或我不知道的更好的解决方案?你能分享一下你的实现吗?
一个(非常未成熟的)想法:
#!/bin/bash
# Some sort of simple syntax to describe to Python what arguments to accept
opts='
"a", "append", boolean, help="Append to existing file"
"dir", str, help="Directory to run from"
"o", "overwrite", boolean, help="Overwrite duplicates"
"R", "recurse", boolean, help="Recurse into subdirectories"
"v", "verbose", boolean, help="Print additional information"
'
# Takes in CLI arguments and outputs a sanitized structure (JSON?) or fails
p=$(parse.py "Runs complex_function with nice argument parsing" "$opts" "$@")
if [ $? -ne 0 ]; exit 1; fi # while parse outputs usage to stderr
# Takes the sanitized structure and an argument to get
append=$(arg.py "$p" append)
overwrite=$(arg.py "$p" overwrite)
recurse=$(arg.py "$p" recurse)
verbose=$(arg.py "$p" verbose)
cd $(python arg.py "$p" dir)
complex_function $append $overwrite $recurse $verbose
只需要两行代码和简明的参数说明,就可以开始实际脚本行为了。也许我有点神经,但这似乎比我现在必须做的要好得多。
我看过解析shell脚本参数和类似易于使用的CLI参数解析的维基页面,但是这些模式中很多都感觉不够流畅且容易出错,而且我不喜欢每次编写shell脚本时都需要重新实现它们,尤其是Python、Java等语言有如此好的参数处理库的情况下。
--dir
)无法持续工作,并且存在失败的边缘情况。例如,script.sh -dir /tmp/my-dashed-file -a -b
将返回-a -b -dashed -dir /tmp/my -file
。在'-'
上分割可能是您想要的,这会稍微好一些,但仍然无法处理script.sh -t "This string -10+4/3 shouldn't be parsed"
。一般来说,最好让 shell 分割输入字符串,并让脚本仅进行参数解析。 - dimo414