【问题标题】:What is the significance of backslashes, backticks, and carets in various shells各种shell中的反斜杠、反引号和插入符号有什么意义
【发布时间】:2021-10-17 23:21:09
【问题描述】:

我在 Windows PC 上关注 https://docs.docker.com/get-started/06_bind_mounts/#start-a-dev-mode-container 并被困在这里:

运行以下命令。之后我们会解释发生了什么:

 docker run -dp 3000:3000 \
     -w /app -v "$(pwd):/app" \
     node:12-alpine \
     sh -c "yarn install && yarn run dev"

如果您使用的是 PowerShell,请使用以下命令:

 docker run -dp 3000:3000 `
     -w /app -v "$(pwd):/app" `
     node:12-alpine `
     sh -c "yarn install && yarn run dev"

在使用命令提示符时,我收到错误(尝试了多种变体,如下所示),而在使用 PowerShell 时,我似乎没有收到错误,但在执行 docker ps 时没有运行任何东西。 请注意,我宁愿使用命令提示符而不是 PowerShell,因为我可以在我的 PC 上将 Linux 命令与 ComandPrompt 一起使用。

在使用带有命令提示符的 Dockers 时,反斜杠有什么意义(以及在 PowerShell 中使用刻度线)?

我后来发现docker run -dp 3000:3000 -w /app -v "%cd%:/app" node:12-alpine sh -c "yarn install && yarn run dev" 可以正常工作(去掉反斜杠,放在一行上,并使用%cd% 而不是$(pwd)),但仍然想知道为什么在示例会导致错误。

使用命令提示符

C:\Users\michael\Documents\Docker\app>docker run -dp 3000:3000 \
docker: invalid reference format.
See 'docker run --help'.

C:\Users\michael\Documents\Docker\app>     -w /app -v "$(pwd):/app" \
'-w' is not recognized as an internal or external command,
operable program or batch file.

C:\Users\michael\Documents\Docker\app>     node:12-alpine \
The filename, directory name, or volume label syntax is incorrect.

C:\Users\michael\Documents\Docker\app>     sh -c "yarn install && yarn run dev"
sh: yarn: command not found

C:\Users\michael\Documents\Docker\app>docker run -dp 3000:3000 \ -w /app -v "$(pwd):/app" \ node:12-alpine \ sh -c "yarn install && yarn run dev"
docker: invalid reference format.
See 'docker run --help'.

C:\Users\michael\Documents\Docker\app>docker run -dp 3000:3000 -w /app -v "$(pwd):/app" node:12-alpine sh -c "yarn install && yarn run dev"
docker: Error response from daemon: create $(pwd): "$(pwd)" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed. If you intended to pass a host directory, use absolute path.
See 'docker run --help'.

C:\Users\michael\Documents\Docker\app>

使用 PowerShell

PS C:\Users\michael\Documents\Docker>  docker run -dp 3000:3000 `
>>      -w /app -v "$(pwd):/app" `
>>      node:12-alpine `
>>      sh -c "yarn install && yarn run dev"
849af42e78d4ab09242fdd6c3d03bcf1b6b58de984c4485a441a2e2c88603767
PS C:\Users\michael\Documents\Docker> docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
PS C:\Users\michael\Documents\Docker>

【问题讨论】:

  • 不清楚您所说的“在命令提示符中使用 Linux 命令”是什么意思...但是您需要查看 docker logs 以了解容器实际失败的原因(可能是纱线中有问题过程)
  • @OneCricketeer,在安装 git 时,安装了允许我使用 ls -l 而不是 dir 的工具。
  • 听起来你正在使用“Git Bash”,它不是 CMD。基本上,我认为总体上不推荐使用 WSL2
  • @OneCricketeer 是的,我是。通过它可能会导致问题(不幸的是它不是罪魁祸首)但在看到你的评论之前不记得它叫什么。将签出 WSL2。谢谢

标签: docker powershell command-prompt


【解决方案1】:

这是字符转义。

X 字符(\ 用于 Bash,反引号用于 Powershell,^ 用于 Windows 终端)用于删除下一个字符的任何特定含义。

在行尾使用时,意味着下一个字符(换行符)被完全忽略。

从解释器的角度来看,这使命令本质上是单行命令,但允许您将其拆分为多行以提高可读性。

参考文献

Powershell - About special characters

转义序列以反引号字符 [`] 开头,称为坟墓 重音(ASCII 96),并且区分大小写。反引号字符可以 也称为转义字符。

Bash manual

3.1.2.1 转义字符

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

How-to: Escape Characters, Delimiters and Quotes at the Windows command line

转义 CR/LF 行尾。 ^ 转义字符可用于 通过将长命令分成多行来使长命令更具可读性 并在结尾处转义回车 + 换行 (CR/LF) 行:

ROBOCOPY \\FileServ1\e$\users ^
\\FileServ2\e$\BackupUsers ^
/COPYALL /B /SEC /MIR ^
/R:0 /W:0 /LOG :MyLogfile.txt /NFL /NDL

[...]

需要注意的几点:

行尾的杂散空格(^ 之后)会破坏 命令,这可能很难发现,除非你有一个文本编辑器 显示空格和制表符。如果你想评论一些东西 使用 REM,那么每一行都需要以 REM 为前缀。或者 如果您使用双冒号 :: 作为 REM 注释,它仍然会解析 行尾的插入符号,因此在上面的示例中更改 :: ROBOCOPY… 的第一行将注释掉整个多行 命令。

【讨论】:

    【解决方案2】:

    仍然想知道为什么在示例中使用确切的脚本会导致错误。

    因为\ 字符结尾的命令适用于POSIX 兼容的shell,例如bash,而不适用于cmd.exe

    • POSIX 兼容的 shellshbashdashkshzsh):

      • 使用\ 进行行继续(在下一行继续命令)和一般转义。
      • 使用$varName 来引用环境变量和仅限shell 的变量。
      • 支持 $(...) 在命令行中嵌入命令 (...) 的输出(命令替换)。
      • 支持双引号("...",插值)和单引号('...',逐字)字符串;使用'\'' - 实际上 - 在'...' 中包含'
        (此外,在bashkshzsh 中,有很少使用的ANSI C-quoted 字符串$'...',以及在bashksh 中,可能更罕见的是localizable strings , $"...")。
    • cmd.exe

      • 一般使用^ 进行行继续和转义(仅在未引用的参数中)。
      • 使用%varName% 引用环境变量(唯一支持的变量类型)。
      • 根本不支持命令替换。
      • 仅支持 "..." 字符串(插值)。
    • PowerShell

      • 一般使用`(反引号)进行行继续和转义。
      • 使用$env:varName 引用环境变量,$varName 引用shell-only 变量。
      • 支持$(...),称为子表达式,相当于命令替换(在双引号字符串之外,(...) 通常就足够了)。
      • 支持双引号("...",插值)和单引号('...',逐字)字符串;使用''' 嵌入到'...' 中。
      • 注意:一个常见的缺陷是,与 POSIX 兼容的 shell 和 cmd.exe 相比,PowerShell 具有更多的 metacharacters,尤其是包括 @ { } , ;,因此需要单独的 `-在不带引号的参数中转义或嵌入在带引号的参数中字符串 - 请参阅 this answer

    潜在的行延续陷阱:在所有讨论的shell中,转义字符必须是行的最后一个字符 -甚至不允许尾随(行内)空格(因为转义字符将应用于 it 而不是换行符)。

    以上信息汇总于下表:

    Feature POSIX shell cmd.exe PowerShell
    Line-continuation / escape character Backslash (\) Caret (^) Backtick (`)
    Double-quoted strings (interpolating)
    Single-quoted strings (verbatim)
    Reference environment variables $varName %varName% $env:varName
    Reference shell-only variables $varName ❌ (no such variables exist) $varName
    Command substitutions / subexpressions $(...) (...) / $(...), esp. in strings

    另见:

    【讨论】:

    • 非常全面和高质量的答案。考虑到难以搜索这些类型项目的信息,特别有用。谢谢。
    • 哇,你做得很漂亮!由于我很困惑,请忽略我关于输入命令替换的部分。
    • 知道了,@user1032531。我添加了指向hyperpolyglot.org/shell 的链接,这是这些shell 的综合并列,但请注意缺少细节,尤其是。关于 PowerShell。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-05
    • 1970-01-01
    相关资源
    最近更新 更多