2013-07-14 80 views
0

我想实现一个bash函数,该函数将命令的参数作为命令运行,同时(可以选择)在打印命令之前。想想安装脚本或测试运行器脚本。在bash中使用双引号引起的shell引用

只需使用

function run() { 
    echo "Running [email protected]" 
    "[email protected]" 
} 

不肯让我来区分run foo arg1 arg2run foo "arg1 arg2"的电话,所以我需要正确逃生的论点。

我最好的拍摄迄今

function run() { 
    echo -n "Running" 
    printf " %q" "[email protected]" 
    echo 
    "[email protected]" 
} 

其中一期工程:

$ run echo "one_argument" "second argument" argument\"with\'quotes 
Running echo one_argument second\ argument argument\"with\'quotes 
one_argument second argument argument"with'quotes 

,但不是很优雅。我怎样才能实现

$ run echo "one_argument" "second argument" argument\"with\'quotes 
Running echo one_argument "second argument" "argument\"with'quotes" 
one_argument second argument argument"with'quotes 

的输出,即如何才能让printf把周围需要报价参数引号,并在其中正确转义引号,使输出可以正确copy'n'pasted?

+0

你可以在_all_参数周围加上引号,而不仅仅是那些需要它的?你可以绕过所有参数的双引号,如下所示:tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_03.html – kevinsa5

+0

这将是丑陋的,如果参数包含引号,则会不正确。为了调试不那么严重的输出,但我仍然希望输出是正确的。 –

+0

啊,我明白了。我对BASH的了解不足以帮助过去,抱歉。 – kevinsa5

回答

1

我不认为有什么你想要的优雅的解决方案,因为"[email protected]"处理bash任何命令才能看到它。你必须手动重新构建命令行:

#!/bin/bash 

function run() { 
    echo -n "Running:" 
    for arg in "[email protected]"; do 
    arg="$(sed 's/"/\\&/g' <<<$arg)" 
    [[ $arg =~ [[:space:]\\\'] ]] && arg=\"arg\" 
    echo -n " $arg" 
    done 
    echo "" 

    "[email protected]" 
} 

run "[email protected]" 

输出:

$ ./test.sh echo arg1 "arg 2" "arg3\"with'other\'\nstuff" 
Running: echo arg1 "arg 2" "arg3\"with'other\'\nstuff" 
arg1 arg 2 arg3"with'other\'\nstuff

注意,有一些角落情况下,你将无法得到确切的输入命令行。这发生在你传递参数是bash扩展传递它们之前,例如:

$ ./test.sh echo foo'bar'baz 
Running: echo foobarbaz 
foobarbaz 
$ ./test.sh echo "foo\\bar" 
Running: echo "foo\bar" 
foobar
+0

这看起来非常类似于@MohammadJavadNaderi在评论中链接的[答案](http://stackoverflow.com/questions/1668649/how-to-keep-quotes-in-args/1669493#1669493);它似乎不处理引用特殊字符,如'''本身。 –

+0

@JoachimBreitner查看更新的答案。 –

+0

你不能将这些参数“移”掉 - 打印后你将无法执行命令!此外,您的正则表达式将匹配其中一个字符{“a”,“c”,“e”,“p”,“s”,“:”} - 您需要'[[:space:]]' –

2

这将引用的一切:

run() { 
    printf "Running:" 
    for arg; do 
     printf ' "%s"' "${arg//\"/\\\"}" 
    done 
    echo 
    "[email protected]" 
} 
run echo "one_argument" "second argument" argument\"with\'quotes 
Running: "echo" "one_argument" "second argument" "argument\"with'quotes" 
one_argument second argument argument"with'quotes 

该版本仅报价包含双引号或空白的参数:

​​
Running: echo one_argument "second argument" "argument\"with'quotes" 
one_argument second argument argument"with'quotes