【问题标题】:How to pass arguments with special characters to call shell script如何传递带有特殊字符的参数来调用 shell 脚本
【发布时间】:2017-02-08 06:25:00
【问题描述】:

使用所需参数调用 .sh(shell 脚本):-

sh home/example.sh --context_param dbUserName=username --context_param dbPassword=exam!ple##### --context_param resultDate=2017-01-13

使用参数 dbUsername 和密码调用 example.sh 但出现以下错误:-

-bash: !ple#####: 未找到事件

我认为特殊字符会限制命令的执行。然后我必须如何传递特殊字符。任何帮助都将不胜感激。

【问题讨论】:

    标签: linux bash shell quoting


    【解决方案1】:

    这样传递:

    exam\!ple\#\#\#\#\#
    

    测试:

    echo exam\!ple\#\#\#\#\#
    

    【讨论】:

      【解决方案2】:

      换行,

      dbPassword=exam!ple#####
      

      到,

      dbPassword='exam!ple#####'
      

      避免!(历史扩展)在bash中被特殊对待

      来自man bashQUOTING 子部分,

      当使用命令历史扩展工具时(参见下面的历史扩展),历史扩展字符,通常是 !,必须被引用以防止历史扩展。

      HISTORY EXPANSION下的更多内容

      历史扩展是由 历史扩展角色的出现,就是!经过 默认。只有反斜杠(\)和单引号可以引用历史 扩展字符。

      此外,最好引用所有 name-value 对,以防止 shell 进行分词。

      sh home/example.sh --context_param dbUserName="username" --context_param dbPassword='exam!ple#####' --context_param resultDate="2017-01-13"
      

      关于分词,来自man页面,

      分词

      Shell 会扫描双引号内未出现的参数扩展、命令替换和算术扩展的结果以进行分词。 shell 将IFS 的每个字符视为一个分隔符,并使用这些字符作为字段终止符将其他扩展的结果拆分为单词

      【讨论】:

      • Inian 感谢您分享宝贵的知识。就像我已经尝试过这些情况一样,您确定只有这应该是解决方案吗,因为在执行您建议的相同操作后出现错误,现在我认为这可能是因为脚本不正确。所以只是确认你确定解决方案?
      • @RanjitSingh:以sh home/example.sh --context_param dbUserName="username" --context_param dbPassword='exam!ple#####' --context_param resultDate="2017-01-13" 运行它不会引发任何错误w.r.t 引用,但我不能保证你的脚本的其余部分。
      • 我试图从命令行运行 nextcloud occ 命令,并试图将密码作为参数之一传递,当它失败时,因为密码具有特殊字符。所以这绝对对我有用。确保在引用值时使用单引号,而不是双引号。
      【解决方案3】:

      你可以做以下两件事:

      1. 用反斜杠转义每个特殊符号

        sh home/example.sh --context_param dbUserName=username --context_param dbPassword=exam\!ple\#\#\#\#\# --context_param resultDate=2017-01-13
        
      2. 单引号引用整个论点

        sh home/example.sh --context_param dbUserName=username --context_param dbPassword='exam!ple#####' --context_param resultDate=2017-01-13
        

      来自man bash

      报价

      引用用于删除某些字符或单词对shell的特殊含义。引用可用于禁用 特殊字符的特殊处理,防止保留字被识别为保留字,防止参数扩展。

      在使用命令历史扩展工具时,必须引用历史扩展字符,通常为!,以防止历史扩展。

      共有三种引用机制:转义字符单引号双引号

      不带引号的反斜杠 (\) 是转义字符。它保留后面的下一个字符的文字值,但有例外 的<newline>。如果出现 \<newline> 对,并且反斜杠本身没有被引用,则 \<newline> 被视为行继续 (也就是说,它从输入流中被移除并被有效地忽略)。

      用单引号括起来的字符保留引号内每个字符的字面值。可能不会出现单引号 在单引号之间,即使前面有反斜杠。

      双引号括起来的字符保留引号内所有字符的字面值,$,`,\ 和启用历史扩展时的 @987654330 除外@。字符$ 和` 在双引号中保留其特殊含义。反斜杠 仅当后跟以下字符之一时才保留其特殊含义:$、`、"\<newline>。双引号可以用反斜杠在双引号中引用。如果启用,将执行历史扩展,除非 ! 出现在 double 中 引号使用反斜杠转义。 ! 前面的反斜杠不会被删除。

      特殊参数*@在双引号中时有特殊含义。

      $'string' 形式的单词会被特殊处理。单词扩展为字符串,并按照 ANSI C 标准的规定替换反斜杠转义字符。

      反斜杠转义序列,如果存在,解码如下:

                \a     alert (bell)
                \b     backspace
                \e
                \E     an escape character
                \f     form feed
                \n     new line
                \r     carriage return
                \t     horizontal tab
                \v     vertical tab
                \\     backslash
                \'     single quote
                \"     double quote
                \nnn   the eight-bit character whose value is the octal value nnn (one to three digits)
                \xHH   the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)
                \uHHHH the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHH (one to four hex digits)
                \UHHHHHHHH
                       the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHHHHHH (one to eight hex digits)
                \cx    a control-x character
      

      扩展的结果是单引号的,就好像美元符号不存在一样。

      以美元符号 ($"string") 开头的双引号字符串将导致根据当前语言环境翻译该字符串。如果当前语言环境是 C 或 POSIX,则忽略美元符号。如果字符串被翻译和替换,替换是双引号。

      【讨论】:

        猜你喜欢
        • 2018-12-28
        • 1970-01-01
        • 1970-01-01
        • 2018-07-07
        • 2012-08-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-27
        相关资源
        最近更新 更多