代码之家  ›  专栏  ›  技术社区  ›  rui

连接所有参数并用双引号将其括起来

  •  17
  • rui  · 技术社区  · 15 年前
    function foo() {
    A=$@...
    echo $A
    }
    
    foo bla "hello ppl"
    


    “bla”“你好,ppl”

    我需要做什么来代替省略号?

    6 回复  |  直到 7 年前
        1
  •  24
  •   glenn jackman    15 年前

    @msw有正确的想法(在对这个问题的评论中)。但是,用引号打印参数的另一个想法是:使用 printf :

    foo() { printf '"%s" ' "$@"; echo ""; }
    
    foo bla "hello ppl"
    # => "bla" "hello ppl"
    
        2
  •  6
  •   Fritz G. Mehner    15 年前

    function foo() {
        A=("${@/#/\"}")
        A=("${A[@]/%/\"}")
        echo -e "${A[@]}"
    }
    
    foo bla "hello ppl" kkk 'ss ss'
    

    输出

    "bla" "hello ppl" "kkk" "ss ss"
    
        3
  •  3
  •   ninjalj    15 年前

    您可以使用“$@”将每个参数视为单独的参数,然后在每个参数上循环:

    function foo() {
    for i in "$@"
    do
        echo -n \"$i\"" "
    done
    echo
    }
    
    foo bla "hello ppl"
    
        4
  •  3
  •   msw    15 年前

    function quote_args {
       for i ; do
          echo \""$i"\"
       done
    }
    

    将其引用的参数每行一个,这通常是馈送其他程序的最佳方式。你得到的输出不是你要求的:

    $ quote_args this is\ a "test really"
    "this"
    "is a"
    "test really"
    

    但是它可以很容易地转换,这是大多数shell调用都希望使用的习惯用法:

    $ echo `quote_args this is\ a "test really"`
    "this" "is a" "test really"
    

    但除非它经过另一个 eval 通过,额外的报价可能会把事情搞砸。也就是说, ls "is a file" 将列出文件 is a file 虽然

    $ ls `quote_args is\ a\ file`
    

    "is , a ,和 file" 你可能不想要。

        5
  •  2
  •   Dennis Williamson    15 年前

    不需要循环:

    foo() { local saveIFS=$IFS; local IFS='"'; local a="${*/#/ \"}"; echo "$a"\"; IFS=$saveIFS; }
    

    IFS 在这个简单的例子中不是必需的,特别是在函数退出之前恢复它,因为 local 使用。但是,我将它包含在函数中,以防其他东西进入 国际单项体育联合会

    示例运行:

    $ foo a bcd "efg hij" k "lll mmm nnn " ooo "   ppp   qqq   " rrr\ sss
     "a" "bcd" "efg hij" "k" "lll mmm nnn " "ooo" "   ppp   qqq   " "rrr sss"
    
        6
  •  1
  •   Community CDub    8 年前

    此时唯一一个尊重参数内反斜杠和引号的解决方案是:

    $ concatenate() { printf "%q"" " "$@"; echo ""; }
    $ concatenate arg1 "arg2" "weird arg3\\\\\\bbut\" legal!"
    arg1 arg2 weird\ arg3\\\\\\bbut\"\ legal\!
    

    “%q””

    %问 参数以可重用为shell的格式打印 建议的POSIX$“”语法。

    特殊字符( \ , \b backspace,…)确实会被接收程序解释,即使没有在终端输出中显示解释。

    让我们测试一下:

    # display.sh: Basic script to display the first 3 arguments passed
    echo -e '#!/bin/bash'"\n"'echo -e "\$1=""$1"; echo -e "\$2=""$2"; echo -e "\$3=""$3"; sleep 2;' > display.sh
    sudo chmod 755 display.sh
    
    # Function to concatenate arguments as $ARGS
    # and "evalutate" the command display.sh $ARGS
    test_bash() { ARGS=$(concatenate "$@"); bash -c "./display.sh ""$ARGS"; }
    
    # Test: Output is identical whatever the special characters
    ./display.sh arg1 arg2 arg3
    test_bash    arg1 arg2 arg3
    

    更复杂的测试:

    ./display.sh arg1 "arg2-1:Y\b-2:Y\\b-3:Y\\\b-4:Y\\\\b-5:Y\\\\\b-6:Y\\\\\\b" "arg3-XY\bZ-\"-1:\-2:\\-3:\\\-4:\\\\-5:\\\\\-6:\\\\\\-"
    test_bash    arg1 "arg2-1:Y\b-2:Y\\b-3:Y\\\b-4:Y\\\\b-5:Y\\\\\b-6:Y\\\\\\b" "arg3-XY\bZ-\"-1:\-2:\\-3:\\\-4:\\\\-5:\\\\\-6:\\\\\\-"
    

    display.sh ,我们正在使用 echo -e 而不是仅仅 echo printf

    -e类 启用反斜杠转义的解释

    如果-e有效,则识别以下序列:

    • \反斜杠
    • \b退格

    注: \乙 是退格字符,因此它会删除示例中的Y。

    感谢接受的回答 Danny Hong answer 在“如何在双引号内转义双引号?”