【问题标题】:Passing a file as one string argument to a bash function将文件作为一个字符串参数传递给 bash 函数
【发布时间】:2019-04-17 03:52:10
【问题描述】:

为了方便起见,我有一个包装了java 命令的 Bash 函数。该命令接受一个实际上是 JSON 并且可能有点大的参数,所以我更喜欢将它存储在一个多行文件中。

这是一个简化的例子。

Java 程序 Test 只是按原样打印出它的最后一个命令行参数,并带有 JSON 文件中的换行符和缩进。这有效:

$ java Test -s test "$(cat test.json)"
{
    "id": 123,
    "name": "Test"
}

现在我的 Bash 函数如下所示:

jwt() { java Test $@; }

当我现在用cat“子命令”调用函数时,传递的参数被破坏了:

$ jwt -s test "$(cat test.json)"
{
$ jwt -s test "`cat test.json`"
{

zsh 中可以使用相同的命令行,但我想了解如何使用 bash 来执行此操作。


另一个例子 - 我将使用 echo 而不是 java

这行得通:

$ echo "$(cat test.json)"
{
    "id": 123,
    "name": "Test"
}

Bash 函数:

e() { echo $@; }

调用它:

$ e "$(cat test.json)"
{ "id": 123, "name": "Test" }

令人惊讶的是,这里的空白被压缩为单个空格。想知道与 Java 有什么不同。

【问题讨论】:

  • 引用它:e() { echo "$@"; }
  • @anubhava 将所有命令行参数放入一个字符串中,这不是我在实践中想要的。第二个例子有点过于简化了,但正如你在第一个例子中看到的那样,可能还有其他参数。
  • 如果您使用单个参数调用e,则"$@""$*" 之间没有区别。我看不到e "$(cat test.json)" 如何产生您声称的输出。使用 either $*$@(未加引号)会在应用分词后导致 echo 出现多个参数。
  • @anubhava 我已纠正,您的解决方案似乎有效。我明天上班试试。谢谢。
  • ShellCheck 对于调试 shell 脚本非常有用。我喂它你的功能,得到了这个:SC2068 - Double quote array expansions to avoid re-splitting elements.

标签: bash shell command-line-arguments


【解决方案1】:

"$@" 是一种特殊情况,它可以按预期正确保留参数。

$ cat Foo.java
public class Foo {
  public static void main(String[] args) {
    for (String arg: args) {
      System.out.println("'"+arg+"'");
    }
  }
}

$ cat foo.sh
#!/bin/sh

foo() {
  java Foo "$@"
}

foo arg1 arg2 "arg 3"

$ sh foo.sh
'arg1'
'arg2'
'arg 3'

【讨论】:

    猜你喜欢
    • 2017-09-04
    • 1970-01-01
    • 1970-01-01
    • 2017-05-03
    • 2012-05-25
    • 2020-12-19
    • 2017-04-25
    • 2012-07-26
    • 1970-01-01
    相关资源
    最近更新 更多