提问人:zeroweb 提问时间:9/16/2020 最后编辑:Cyruszeroweb 更新时间:9/16/2020 访问量:684
Bash 打印除 first 之外的所有参数 - print 返回文件名
Bash print all arguments except first - print returns file names
问:
我有一个 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)它用文件名替换了*。
我试图用“逃避那些,但它没有用。有没有办法解决这个问题?我哪里做错了?
答:
0赞
MarcoLucidi
9/16/2020
#1
被扩展,因为你正在做一个没有引号的.尝试添加如下引号:*
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: * * * * *"
$
评论
1赞
glenn jackman
9/16/2020
这仍然将其余的参数存储为 REST_ARGS 变量中的单个字符串,尽管您已经保护了单词拆分和路径名扩展。通常,在参数中存储文本引号是一个坏主意:将参数传递给的命令必须处理文本引用,否则会引发错误
0赞
MarcoLucidi
9/16/2020
在这种特殊情况下,@glennjackman是一个问题?我同意在参数中存储引号是一个坏主意,但我从问题中了解到 OP 想要保留它们。That still stores the rest of the args as a single string in the REST_ARGS variable
1赞
glenn jackman
9/16/2020
#2
隐藏命令行参数的唯一可靠方法是在数组中:
#!/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
0赞
Léa Gris
9/16/2020
#3
你要求的:
#!/usr/bin/env sh
echo "$1"
shift
printf '"%s" ' "$@"
# or alternatively:
# env printf '%q ' "$@"
echo
评论
cmd a b
cmd "a" "b"
a
b