如何在别名数组中打印“`”和“%”字符?

abu*_*iri 4 bash keyboard alias

我的键盘上的按钮有一些问题,我已经更换了 3 次键盘。我暂时使用 printf 作为一些文本编辑器。我需要在数组中打印“`”和“%”字符,并在别名上使用颜色,但根本不起作用。
基本上在 bash 中是这样的:

printf "[%c%c%c]\n", '`', '`', '%';
Run Code Online (Sandbox Code Playgroud)

输出 :

[``%]
Run Code Online (Sandbox Code Playgroud)

我试试这个:

alias key='printf "\n\033[33m= "[ %c%c%c~+ |\ ]\n\n", '`', '`', '%'" '
Run Code Online (Sandbox Code Playgroud)

关于别名我收到此错误:

]nn, , %: command not found
Run Code Online (Sandbox Code Playgroud)

别名中应包含哪些格式字符?

提前致谢。

Raf*_*ffa 6

您在别名中使用反引号“`”...这些用于命令替换bash...虽然是旧样式,但不应该使用,因为它们可能会在将来的某个时候过时,以支持当前的命令替换语法$( ... ).. .它们需要被转义,以便您能够printf像您一样将它们作为参数传递给并作为字面反引号......就像这样:

alias key='printf "\n\033[33m [%s%s%s]\n\n" "\`" "\`" "%"'
Run Code Online (Sandbox Code Playgroud)

另一种对你有用的方式即:

printf "[%c%c%c]\n", '`', '`', '%'
Run Code Online (Sandbox Code Playgroud)

是因为它们被括在单引号中,这是告诉 bash 不要将它们处理为命令替换标记的另一种方式...但是当您在别名字符串中使用它并添加更多单引号时,整个引用边界翻转并打开围绕反引号即:

printf "[%c%c%c]\n", '`', '`', '%'
Run Code Online (Sandbox Code Playgroud)

反引号由 bash 处理。

printf在 bash 中不需要用逗号分隔参数,尽管应该可以很好地解析。

%c此外,通常不需要使用字符说明符,因为字符串说明符%s可以与正确的引用/转义一起使用,并且应该更加灵活。


ste*_*ver 6

忽略无关的逗号 ( ,) 字符,这里的问题是引用。

反引号是命令替换的不推荐语法,并在双引号内保留特殊含义。所以虽然

printf '%c%c\n' '`' '`'
Run Code Online (Sandbox Code Playgroud)

作品,

printf '%c%c\n' "`" "`"
Run Code Online (Sandbox Code Playgroud)

相当于printf '%c%c\n' "$(" ")",它尝试将文字空间作为命令执行并将结果作为参数传递给printf

$ printf '%c%c\n' "`" "`"
 : command not found
Run Code Online (Sandbox Code Playgroud)

那么,为什么不能简单地使用单引号形式定义别名呢?出色地:

  1. 单引号不能嵌套,所以

    alias key='printf '%c%c\n' '`' '`' ' 
    
    Run Code Online (Sandbox Code Playgroud)

    'printf ', %c%c\n, 和' '连接成一个格式字符串,留下(不带引号)

    `' '`' '
    
    Run Code Online (Sandbox Code Playgroud)

    您的交互式 shell 的扩展相当于$(' ')' '- 再次尝试执行文字空间。

  2. 另一方面,如果您尝试使用外部双引号

    alias key="printf '%c%c\n' '`' '`' "
    
    Run Code Online (Sandbox Code Playgroud)

    然后根据上面链接的引用规则,引号变成文字,并且您的 shell 再次扩展' '为命令。

有效的是转义单引号:

$ unalias key
$ alias key='printf "%c%c\n" '\''`'\'' '\''`'\'' '
$ 
$ key
``
Run Code Online (Sandbox Code Playgroud)

对于您的完整别名,那就是

alias key='printf "\n\033[33m= [ %c%c%c~+ |\ ]\n\n" '\''`'\'' '\''`'\'' "%" '
Run Code Online (Sandbox Code Playgroud)

(尽管引用"%"并不是严格必要的)。

如果“倾斜的牙签”变得难以处理,您可以考虑使用 shell 函数而不是别名,从而消除一级引用1

$ key () { printf '\n\033[33m= [ %c%c%c~+ |\ ]\n\n' '`' '`' '%' ; }
$ 
$ key

= [ ``%~+ |\ ]
Run Code Online (Sandbox Code Playgroud)

另请参见在 Bash 中,何时使用别名、何时使用脚本以及何时编写函数?


  1. 事实上,bash 手册中关于别名的部分“对于几乎所有用途,shell 函数都优于别名”。