AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 437965
Accepted
iconoclast
iconoclast
Asked: 2018-04-16 13:58:06 +0800 CST2018-04-16 13:58:06 +0800 CST 2018-04-16 13:58:06 +0800 CST

为什么 alias foo='echo "This is a quote: \'"' 不起作用?[复制]

  • 772
这个问题在这里已经有了答案:
为另一个命令包装一个包含单引号和双引号的命令 1 个答案
4年前关闭。

为了在我尝试shopt在 Zsh 中使用而不是时提醒自己setopt,我创建了以下别名,首先在 shell 提示符下对其进行测试:

$ alias shopt='echo "You\'re looking for setopt. This is Z shell, man, not Bash."'

尽管外部单引号匹配和内部双引号匹配,并且撇号被转义,但我被提示完成关闭引号:

dquote > _

这是怎么回事?

似乎转义被忽略了,或者由于多个解释级别而需要双重转义......所以,为了验证这个理论,我尝试了双重转义(以及三次转义,等等on) 一直到:

alias shopt='echo "You\\\\\\\\\\\\\\\\\\\\\\'re looking for setopt. This is Z shell, man, not Bash." '

并且从未见过任何不同的行为。这对我来说毫无意义。什么样的怪异巫毒会阻止外壳按我预期的方式运行?

实际的解决方案是不使用引号echo,因为它实际上并不需要任何引号,并使用双引号alias,并转义撇号,以便在编辑文本时将其忽略echo。然后所有的实际问题都消失了。

你能帮助我吗?我需要解决这个令人困惑的问题。

zsh quoting
  • 5 5 个回答
  • 8053 Views

5 个回答

  • Voted
  1. Best Answer
    Stéphane Chazelas
    2018-04-16T14:06:07+08:002018-04-16T14:06:07+08:00

    这是zsh,伙计,不是fish。

    在zsh中,就像在每个 Bourne-like shell(以及csh)中一样,单引号是强引号,其中没有转义(除非使用@JdeBP 暗示的选项来rcquotes模拟引号¹)。单引号字符串中不能有单引号,您需要首先关闭单引号字符串并使用另一种引用机制(如or )输入文字单引号:zshrc\"

    alias shopt='echo "You'\''re looking for setopt. This is Z shell, man, not Bash."'
    

    或者:

    alias shopt='echo "You'"'"'re looking for setopt. This is Z shell, man, not Bash."'
    

    虽然你也可以这样做:

    alias shopt="echo \"You're looking for setopt. This is Z shell, man, not Bash.\""
    

    ("..."是较弱的引号,其中几个字符,包括\(这里用于转义嵌入的") 仍然是特殊的)。

    或者:

    alias shopt=$'echo "You\'re looking for setopt. This is Z shell, man, not Bash."'
    

    ($'...'是来自 ksh93 的另一种引用,'可以用 进行转义\')。

    (顺便说一句,您也可以使用标准set -o代替setoptin zsh. bash,由于历史原因,有两组选项,一组是您设置的,set -o一组是用shopt;zsh像大多数其他外壳一样只有一组选项)。


    ¹ 在rcPlan9 的 shell 中,也有类似 unix 的版本,单引号是唯一的引用机制(反斜杠和双引号是那里的普通字符),输入文字单引号的唯一方法是 with ''inside单引号,所以使用zsh -o rcquotes,你可以这样做:

    alias shopt='echo "你正在寻找 setopt。这是 Z shell,伙计,不是 Bash。"'

    • 44
  2. JdeBP
    2018-04-16T14:15:47+08:002018-04-16T14:15:47+08:00
    shopt='回显“你”

    这不是巫毒。这是正常的 POSIX shell 引用。 单引号字符串中没有转义机制。它们总是在下一个单引号处终止。有一个 Z shell 扩展,可以使两个连续的单引号字符串在它们之间放置一个单引号,您可以使用它。或者您可以终止单引号字符串,使用转义(或实际上是非单引号)单引号,然后开始第二个单引号字符串。

    或者你不能在你的信息中使用缩写。☺

    进一步阅读

    • “单引号”。 外壳命令语言。基本规格。IEEE 1003.1:2017。公开组
    • “引用”。 壳牌语法。Z Shell 手册。
    • 13
  3. Kevin
    2018-04-17T08:20:12+08:002018-04-17T08:20:12+08:00

    其他答案很好地解释了为什么您会看到这种行为。但是,如果我可以就如何实际解决这个问题提出建议:

    不要对任何复杂的东西使用别名。

    当然,你可以绞尽脑汁想弄清楚如何嵌套 N 层引号,但对于别名来说,这很少值得。当别名足够复杂以至于它的引用变得不平凡时,只需切换到 shell 函数:

    shopt(){
        echo "You're looking for setopt. This is Z shell, man, not Bash."
    }
    

    这将删除一整层引号,允许您稍后向 shell 函数添加更多代码,并且通常更易于阅读。它还允许对参数的插入方式和位置进行更精细的控制,而不是“只需替换行的开头,让剩余的单词放在可能的地方”的别名方法。例如,使用您的(更正后的)别名,如果您键入以下内容:

    shopt -s some_opt
    

    ...然后你会得到这个输出:

    You're looking for setopt. This is Z shell, man, not Bash. -s some_opt
    

    这可能不是你想要的。shell 函数将使用您传递给它的任何参数,并默默地丢弃它们。

    • 13
  4. Zanna
    2018-04-16T23:50:28+08:002018-04-16T23:50:28+08:00

    如果您不想与引号作斗争,请使用另一个字符,例如 Unicode U+2019,而不是'撇号。

    按住Ctrl+Shift并键入u2019,此字符将出现’(呃...取决于您的语言环境?)。

    % alias shopt='echo You’re looking for setopt. This is a Z shell, woman, not Bash.'
    % shopt -s dotglob
    You’re looking for setopt. This is a Z shell, woman, not Bash. -s dotglob
    

    (U+2019) 的这种用法’是正确的,因为该字符正式用作撇号。Unicode 标准 10.0 版明确推荐这种用法。该标准承认'(U+0027) 通常用作撇号,因为它存在于 ASCII 和键盘上,并且似乎允许这样做。但它随后指出’(U+2019)更适合用作标点符号的撇号(并以缩略语为例)。唯一’不推荐使用 (U+2019) 的撇号是那些用作变音符号而不是标点符号的撇号;这些写得最好ʼ(U + 02BC)。来自标准第 6.2 节中的撇号(第 276 页):

    撇号

    U+0027 APOSTROPHE是撇号最常用的字符。由于历史原因,U+0027 是一个特别重载的字符。在 ASCII 中,用于表示标点符号(如右单引号、左单引号、撇号标点符号、竖线或素数)或修饰字母(如撇号修饰符或重音符号)。标点符号一般会打断单词;修饰字母通常被认为是单词的一部分。

    设置文本时,首选 U+2019 右单引号作为撇号,但大多数键盘上仅存在 U+0027。软件通常提供一种工具,用于将 U+0027 APOSTROPHE自动转换为上下文选择的弯引号字形。在这些系统中,数据流中的 U+0027 始终表示为一条垂直直线,永远不能表示弯撇号或右引号。

    字母撇号。U+02BC MODIFIER LETTER APOSTROPHE是首选,其中撇号表示修饰字母(例如,在音译中表示声门塞音)。在后一种情况下,它也被称为字母撇号。

    标点撇号。U+2019 RIGHT SINGLE QUOTATION MARK是首选,其中字符表示标点符号,至于缩写:“ Weve been here before. ” 在后一种情况下,U+2019 也被称为标点撇号。

    一个实现不能假设用户的文本总是遵守这些字符之间的区别。文本可能来自不同的来源,包括来自不区分字母撇号和标点撇号/右单引号的其他字符集的映射。在那种情况下,它们通常都会用 U+2019 来表示。

    因此,U+2019 的语义依赖于上下文。例如,如果两边都被字母或数字包围,则它表现为文本中的标点符号,并且不分隔单词或行。

    • 5
  5. iconoclast
    2018-04-16T14:04:55+08:002018-04-16T14:04:55+08:00

    一条现已删除的评论给了我提示,让我得到了一半的答案。

    在单引号字符串中转义单引号是不可能的。

    双引号字符串中不存在此限制,因为我在最终解决方案中肯定会在双引号字符串中转义单引号:

    alias shopt="echo You\'re looking for setopt. This is Z shell, man, not Bash."
    
    • 4

相关问题

  • 符号链接所有点文件和目录

  • 为什么命令 echo `echo \\\z` 输出 \z?

  • 如何在`zsh`中增加一个动态命名的变量

  • 为什么我不能在 zsh 中定义一个名为 path 的只读变量?

  • U-Boot 参数的简写语法

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    ssh 无法协商:“找不到匹配的密码”,正在拒绝 cbc

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    如何卸载内核模块“nvidia-drm”?

    • 13 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add 返回:“连接代理时出错:没有这样的文件或目录” 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve