【问题标题】:Using "$@" inside others quotes in bash在bash中的其他引号内使用“$@”
【发布时间】:2013-02-08 00:00:16
【问题描述】:

这是我要执行的 bash 脚本的代码:打开一个新控制台并在其中执行带有文件列表的 clamscan

gnome-terminal -x sh -c "clamscan $@"

在这里展开后,如果给脚本的 2 个参数是
file1.txt file2.txt

,那么真正执行的是什么
gnome-terminal -x sh -c 'clamscan file1.txt' file2.txt

如您所见,只有clamscan file1.txt 被执行。

如果我尝试另一种方式来编写代码

gnome-terminal -x sh -c "clamscan \"$@\""

这是展开结果

gnome-terminal -x sh -c 'clamscan "file1.txt' 'file2.txt"'

效果不好。
有谁知道如何正确地将"$@" 整合到其他引号中?

编辑 我的目标是在扩展后拥有类似

gnome-terminal -x sh -c 'clamscan "file1.txt" "file2.txt"'

【问题讨论】:

  • 单引号不展开变量,所以展开结果为gnome-terminal -x sh -c 'echo $@'$@不展开,什么都不显示。
  • 是的,但是当sh 启动命令时,它会扩展给定的字符串。你试过了吗?
  • 是的,我刚刚尝试过,但没有显示任何内容。带简单引号的$@第一次不展开,第二次用sh展开,但被视为未知变量。
  • 不管有没有都不能。你试过了吗:gnome-terminal -x sh -c "echo \$@"
  • 为什么不使用$* 而不是$@$@ 等效于 "$1" "$2"$*is "$1 $2"

标签: bash command-line-arguments quotes


【解决方案1】:

试试:

gnome-terminal -x sh -c `echo "$@"`

虽然我不确定我是否理解脚本最终试图做什么(看来您想要执行一个或多个文件名中可能包含空格的文件)。

【讨论】:

  • 我的错。我简化了这个例子,认为它会更清楚。这是原始代码gnome-terminal -x sh -c "clamscan -r $@ | less" 我想给clamscan(或任何二进制文件)一个文件名列表,每个文件名都用引号引起来,因为它们可能包含空格。你的解决方案不符合我的需要。
【解决方案2】:

试试这个

#!/bin/bash

params=("$@")

for i in "${params[@]}"
do
    string="${string} \'$i\'"
done;

// subst with your full command, this is only for test purposes
sh -c "echo ${string}"  

测试:

[root@myhost test]# sh ./script.sh aaaa "bbbb cccc"
'aaaa' 'bbbb cccc'

【讨论】:

  • 如果任何参数包含单引号怎么办?
【解决方案3】:

来自man bash

3.4.2 特殊参数
@
扩展到位置参数,从一个开始。当扩展出现在双引号内时,每个参数都扩展为一个单独的单词。也就是说,“$@”等价于到“$1”“$2”……。

重要的部分是等价,它确实扩展为"$1" "$2",即用双引号。如果需要,有两种选择,自己准备参数

for i in "$@"; do
    args="$args \"$i\""
done

gnome-terminal -x clamscan $args

或将部分命令行放入脚本中

script.sh:

clamscan "$@"

然后调用它

gnome-terminal -x script.sh file1.txt file2.txt

【讨论】:

  • 太好了,你的 for 语句正是我想要的。
  • 如果任何参数包含引号怎么办?
  • @krlmlr 我不太明白这个问题。为什么你认为引号很特别?您可以使用脚本for f in "$@"; do echo "$f"; done 自己轻松测试,并使用适当的参数sh test.sh 'a"' "'b" c 调用它。
  • @OlafDietsche:我认为他们可以混淆一些东西,但显然它只是有效:-)
【解决方案4】:

您可以使用变量替换:${@/ /\\ }

【讨论】:

  • 不错的发现。它适用于 $* 变量,您需要替换每次出现的空格:${*// /\\ }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-17
  • 1970-01-01
  • 2013-11-19
  • 2019-08-09
  • 1970-01-01
  • 1970-01-01
  • 2022-01-07
相关资源
最近更新 更多