【问题标题】:JSON for command-line arguments用于命令行参数的 JSON
【发布时间】:2014-12-05 15:25:58
【问题描述】:

假设我想写一个工具,需要接受轻微结构化的数据,使用 json 作为命令行参数是否合理,同时使用环境?

例如

fudge_files "['file1', 'file2']"  # here list of files could be used
fudge_files --dirs "['dir1', 'dir2']" pattern.* another*.foo

或者在一个更复杂的例子中

fudge_files --dst "{'txt': ['/foo', '/bar'], 'pdf': ['/foo']}" pattern.*

这是个好主意还是坏主意?

有什么陷阱?

【问题讨论】:

    标签: json command-line scripting


    【解决方案1】:

    大多数(所有)shell 都会看到单引号和 dbl 引号,并按照其标准程序处理它们。

    要保留引号以便它们作为数据传入,您需要对它们进行转义,即

    \"[\'file1\', \'file2\']\"
    

    一旦您的数据开始包含合法的“\”字符,它就会变得非常难看。您可以想出一些技巧,但这会很痛苦,而且您可能会花费 大量 时间来尝试调试与此类引用相关的问题。

    并且,如果你坚持并让它发挥作用,那么,2-3 个月后,你可能会想“我可以将其中的一些放入变量中并使用eval”或其他疯狂的方式将变量扩展为字符串.现在你真的要陷入调试噩梦了。

    另外,我使用 shell ANSI 字符串进行了快速测试,看看是否有帮助,但是

    $ var=$'"['file1', 'file2']"'
    $ echo $var
    "[file1, file2]"
    $ echo "$var"
    "[file1, file2]"
    $ var=$""['file1', 'file2']""
    -ksh: file2]: not found [No such file or directory]
    

    ANSI 字符串是定义为$'My Static ANSI String'$"myANSIString with $var input" 的字符串 请注意,即使在第一个示例中,shell 如何在第一次机会时匹配单引号,并将它们从您的输入字符串中剥离出来。希望是echo 剥离了它们,我在第二行echo 使用了最佳实践,并用引号包围了"$var"。不,单引号消失了。 :-(

    我没有太多使用 ANSI 字符串的经验,因此其他人可能会提供一种解决方案,以保持单引号和 dbl 引号不变。

    否则,我认为这不起作用。


    您的工作流程不是很清楚,但猜测某些东西正在发出这些值(我希望您不必键入它们),我认为您最好将它们放入文件中。如果一个单独的程序将它们打印到终端,那么只需重定向到一个文件中

      json_emitting_program --args .... > $tmpFile
    

    或者使用旨在消除 tmp 文件的 Unix 工具,管道 |,并编写您的工具以从 std-in 读取其数据,而不是作为命令行参数。

    那你会说要么

      json_emitting_program --args .... | fudge_files
    

    或者,使用 tmp 文件

    fudge_files < "$tmpFile"
    

    如果您的数据源在 MS Windows 输出中(例如),您可以使用 Unix here-documents 在文件上创建临时文件,类似于

     cat - > $tmpFile << EOS
     paste your input here
     and here
     etc
     EOS
    

    请注意,EOS 必须在它自己的一行上,没有尾随空格。

    如果操作正确,shell 应该会向您返回提示。

    确认文件存在并且是最新的

     ls -l $tmpFile
    

    和上面一样,运行你的程序

    fudge_files < "$tmpFile"
    

    如果您不知道,您可以创建 tmpFile 并简单地分配给您想要命名的任何路径/文件:

    tmpFile=/path/to/myTempFile
    

    IHTH

    【讨论】:

    • 关于在 shell 脚本中重用复杂参数的要点。我对您的示例 $'"[...]"' 有点困惑,它有一层额外的引号;还通过您断言必须转义所有引号。转义和内容使用不同的引号还不够吗?
    • 是的,$'"[...]"' 示例是 shell 的高级功能(ANSI 字符串有两种形式,$'..str.'$".strW$vars.")。不幸的是,我对它们没有太多经验,除了我知道我所包含的示例是有效的。我的观点是,当使用 $'...' 表单时,示例字符串中的内部单引号会丢失,并且使用 ANSI 字符串中的 `$'"..."' 时,您的示例字符串将导致错误shell 尝试评估该行。
    • 请参阅stackoverflow.com/questions/25436988/…,了解有关printf 的bash shell 版本及其功能"%q 的文章,这可能会对您有所帮助。 ....但是...再次,尝试在命令行上读取这样的字符串是错误的方法。花点时间获取fudge_files,这样它就可以从标准输入(管道或重定向)中读取,您将拥有一个更加灵活和稳定的解决方案。 ;-) 祝你好运。
    • @qarma : 你有机会尝试通过curl 发送数据吗?我在 S.O. 上看到很多关于 jsoncurl 和命令行的类似查询。基本上curl -X POST --data @/path/to/dataFile ${URL} 可能会有所帮助。祝你好运。
    • 在一个奇怪的命运转折中,curl 或requests 最终参与其中。但是,此结构化数据不会逐字发送。我的工具实际上会使用这些数据来映射文件系统中的对象,将其转换为自定义格式等。想法是为一组工具提供统一的 API。
    猜你喜欢
    • 2021-10-30
    • 1970-01-01
    • 2017-06-26
    • 2011-11-21
    • 2012-07-12
    • 2018-09-28
    • 2016-03-25
    • 2012-10-04
    • 2021-02-04
    相关资源
    最近更新 更多