【问题标题】:Bash print all arguments except first - print returns file namesBash 打印除第一个以外的所有参数 - print 返回文件名
【发布时间】:2021-01-02 12:45:26
【问题描述】:

我有一个 bash 脚本,它应该在两行中打印参数。第一行应该是第一个参数,第二行应该是其余的参数

#!/bin/bash

FIRST_ARG="$1"
shift
REST_ARGS="$@"

echo $FIRST_ARG
echo $REST_ARGS

这适用于普通参数,例如

root@us:~# /bin/bash parse.sh testName test1 test2 test3
testName
test1 test2 test3
root@us:~# 

但是,我想要的是发送一个键值对作为参数,例如

testName "X-Api-Key: 1be0ad48" "Name: someTest" "Interval: * * * * *"

我希望这会产生如下结果

testName
"X-Api-Key: 1be0ad48" "Name: someTest" "Interval: * * * * *"

包括引号。但是,我得到以下结果

root@us:~# /bin/bash parse.sh testName "X-Api-Key: 1be0ad48" "Name: someTest" "Interval: * * * * *"
testName
X-Api-Key: 1be0ad48 Name: someTest Interval: parse.sh parse.sh parse.sh parse.sh parse.sh
root@us:~# 

这里发生了两件我不希望发生的事情。 1) 它删除引号 ", 2) 它用文件名替换 *。

我尝试用 " 转义那些但没有用。有没有办法解决这个问题?我在哪里做错了?

【问题讨论】:

  • 在将参数传递给脚本之前,引号被删除,所以你想要的实际上是不可能的。但根据您想要引号的为什么,有可能实现您的实际目标。对"Preserve Quotes in bash arguments" 的回答有帮助吗?
  • unix.stackexchange.com/q/171346/4667接受的答案的序言中有非常透彻的解释
  • 无论你写cmd a b还是cmd "a" "b",cmd都是用相同的参数调用的,而且这些参数中没有引号。它们只是字符串ab

标签: bash shell arguments quotes


【解决方案1】:

存储命令行参数的唯一可靠方法是在数组中:

#!/bin/bash

first_arg="$1"
shift
rest_args=("$@")
# ........^....^

# show how bash has stored these variables
declare -p first_arg
declare -p rest_args

echo "first = $first_arg"
for arg in "${rest_args[@]}"; do
    echo "arg = $arg"
done

改掉使用 ALLCAPS 变量名的习惯,让 shell 保留这些变量名。有一天你会写PATH=something 然后wonder why your script is broken

【讨论】:

    【解决方案2】:

    * 已扩展,因为您正在执行 echo 而不引用 $REST_ARGS。尝试添加这样的引号:

    #!/bin/bash
    
    FIRST_ARG="$1"
    shift
    REST_ARGS="$@"
    
    echo "$FIRST_ARG"
    echo "$REST_ARGS"
    

    保留双引号的解决方案是使用单引号 ' 像这样引用字符串:

    $ bash parse.sh testName '"X-Api-Key: 1be0ad48"' '"Name: someTest"' '"Interval: * * * * *"'
    testName
    "X-Api-Key: 1be0ad48" "Name: someTest" "Interval: * * * * *"
    $
    

    【讨论】:

    • 这仍然将其余的参数作为单个字符串存储在 REST_ARGS 变量中,尽管您已经保护了分词和路径名扩展。通常,在参数中存储文字引号是一个坏主意:您将参数传递给的命令将不得不处理文字引号,或者抛出错误
    • @glennjackman That still stores the rest of the args as a single string in the REST_ARGS variable 在这种特殊情况下有问题吗?我同意在参数中存储引号是一个坏主意,但我从 OP 想要保留它们的问题中了解到。
    【解决方案3】:

    按照你的要求做:

    #!/usr/bin/env sh
    
    echo "$1"
    shift
    printf '"%s" ' "$@"
    # or alternatively:
    # env printf '%q ' "$@"
    echo
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-21
      • 2011-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多