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
    • 最新
    • 标签
主页 / computer / 问题 / 1531395
Accepted
Kamil Maciorowski
Kamil Maciorowski
Asked: 2020-03-10 03:19:10 +0800 CST2020-03-10 03:19:10 +0800 CST 2020-03-10 03:19:10 +0800 CST

如何方便地在 Bash 中单引号或转义整个命令行?

  • 772

介绍

考虑这样的工具watch可以接受另一个命令(例如ls -l),如下所示:

watch ls -l
# or equivalently
watch 'ls -l'

如果命令更复杂,如果当前 shell 或 get to 解释诸如$variable、*、或之类的内容|,则全部是关于引用/转义。这两个命令是不同的:;&&watch

watch echo "$$"
watch 'echo "$$"'

这些也是:

watch date ; echo done
watch date \; echo done

ssh类似,它可以接受一个或多个参数并构建一个要在服务器上运行的命令。$variable如果本地 shell 解释等|,或者远程 shell,这取决于引用/转义。

并且有些命令sh -c需要包含代码的单个参数,但引用/转义的需要是相似的。事实上watch(or ) 为或类似命令ssh构建了这个单一参数。sh -c


问题

我已经有了要提供给or或类似工具的确切命令。该命令是从历史记录中获取的,或者粘贴到命令行中,或者像要直接执行一样键入;它在我的命令行中逐字记录。命令中的任何内容都不应在到达或类似工具之前进行扩展或解释。在这种情况下,意味着所有的扩展和解释都应该在以后定期发生。在这种情况下,这意味着它应该发生在服务器上。watchsshwatchwatchssh

现在我需要做两件事:

  • watch在开头添加(或其他)。这不是问题。我可以最后做到这一点。
  • 引用和/或转义原始命令。通常,该命令可以包含单引号,因此盲目地使用单引号并不是解决方案。我想我知道正确的通用解决方案:

    • '用'"'"'或替换每个'\'',
    • 用单引号包含整个结果字符串;

    但是手动执行此操作很乏味且容易出错。


问题

我可以让 Bash 根据需要在整个命令行中正确添加一级单引号/转义吗?

(注意:当我回答这个问题时出现了这个问题。)

bash command-line
  • 1 1 个回答
  • 1583 Views

1 个回答

  • Voted
  1. Best Answer
    Kamil Maciorowski
    2020-03-10T03:19:10+08:002020-03-10T03:19:10+08:00

    解决方案

    是的。我的想法是调用一个 shell 函数(在击键时),它将READLINE_LINE使用该${variable@Q}功能进行操作。

    文档的相关部分:

    ${parameter@operator}

    扩展要么是 的值的变换,要么是parameter关于parameter自身的信息的变换,取决于 的值operator。每个operator都是一个字母:

    Q
    扩展是一个字符串,它是以parameter可重复用作输入的格式引用的值。

    (来源)

    READLINE_LINE
    Readline 行缓冲区的内容,用于bind -x[…]。

    (来源)

    以下适用于 Bash 4.4.20:

    _quote_all() { READLINE_LINE="${READLINE_LINE@Q}"; }
    bind -x '"\C-x\C-o":_quote_all'
    

    要测试解决方案,请在命令行中准备一个命令(不要执行),例如

    d="$(LC_ALL=C date)"; printf 'It'\''s now %s\n' "$d"
    

    (引用和整个命令可以简化。故意这样。您可以执行它以确保它是有效的命令,但在继续之前将其放回命令行中。)

    点击Ctrl+ x,Ctrl+o它将被正确引用/转义以用于我们的目的。它看起来像这样:

    'd="$(LC_ALL=C date)"; printf '\''It'\''\'\'''\''s now %s\n'\'' "$d"'
    

    现在您需要做的就是在前面添加watch(或,或其他)并执行。ssh …如果是,watch请注意标题就像

    Every 2.0s: d="$(LC_ALL=C date)"; printf 'It'\''s now %s\n' "$d"
    

    它包含原始命令。该命令正确到达watch,没有部分被过早解释。


    改进

    为方便起见,请考虑以下变体:

    _quote_all() { READLINE_LINE=" ${READLINE_LINE@Q}"; READLINE_POINT=0; }
    

    它将准备行并将光标放在开头,因此您可以watch立即输入。或者甚至可能是这个变体(它故意使用不同的名称,我们正在为它创建一个单独的绑定):

    _prepend_watch() { READLINE_LINE="watch  ${READLINE_LINE@Q}"; READLINE_POINT=6; }
    bind -x '"\C-x\C-w":_prepend_watch'
    

    现在Ctrl+ x, Ctrl+w处理引用,watch自动插入并将光标放在正确的位置供您键入选项。

    使用另一个函数READLINE_POINT,可以处理以下场景:类型watch(或ssh …)后跟命令,其中引用/转义就像要直接执行命令一样。将光标放在命令开始的位置,点击按键,让函数修改从光标到行尾的所有内容。我这里不提供这样的功能;需要的话自己写。


    Yo Dawg,我听说你喜欢引用

    您可以堆叠解决方案。我的意思是你可以离开这个

    df -h | grep -v tmpfs
    

    对此

    watch 'df -h | grep -v tmpfs'
    

    对此

    ssh hostB -t 'watch '\''df -h | grep -v tmpfs'\'''
    

    对此

    ssh -t hostA 'ssh -t hostB '\''watch '\''\'\'''\''df -h | grep -v tmpfs'\''\'\'''\'''\'''
    

    (是的,我知道ssh -J)

    只需点击Ctrl+ x,Ctrl+o并在每个步骤的前面附加一个或几个单词。

    • 5

相关问题

  • 对于 cp 或 mv,是否有等同于 cd - 的东西?

  • Python 的“pass”参数的批处理等价物是什么?

  • 禁用后无法启用 Microsoft Print to PDF

  • Notify-发送窗口下出现的通知

  • 如何从 WSL 打开 office 文件

Sidebar

Stats

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

    如何减少“vmmem”进程的消耗?

    • 11 个回答
  • Marko Smith

    从 Microsoft Stream 下载视频

    • 4 个回答
  • Marko Smith

    Google Chrome DevTools 无法解析 SourceMap:chrome-extension

    • 6 个回答
  • Marko Smith

    Windows 照片查看器因为内存不足而无法运行?

    • 5 个回答
  • Marko Smith

    支持结束后如何激活 WindowsXP?

    • 6 个回答
  • Marko Smith

    远程桌面间歇性冻结

    • 7 个回答
  • Marko Smith

    子网掩码 /32 是什么意思?

    • 6 个回答
  • Marko Smith

    鼠标指针在 Windows 中按下的箭头键上移动?

    • 1 个回答
  • Marko Smith

    VirtualBox 无法以 VERR_NEM_VM_CREATE_FAILED 启动

    • 8 个回答
  • Marko Smith

    应用程序不会出现在 MacBook 的摄像头和麦克风隐私设置中

    • 5 个回答
  • Martin Hope
    CiaranWelsh 如何减少“vmmem”进程的消耗? 2020-06-10 02:06:58 +0800 CST
  • Martin Hope
    Jim Windows 10 搜索未加载,显示空白窗口 2020-02-06 03:28:26 +0800 CST
  • Martin Hope
    v15 为什么通过电缆(同轴电缆)的千兆位/秒 Internet 连接不能像光纤一样提供对称速度? 2020-01-25 08:53:31 +0800 CST
  • Martin Hope
    fixer1234 “HTTPS Everywhere”仍然相关吗? 2019-10-27 18:06:25 +0800 CST
  • Martin Hope
    andre_ss6 远程桌面间歇性冻结 2019-09-11 12:56:40 +0800 CST
  • Martin Hope
    Riley Carney 为什么在 URL 后面加一个点会删除登录信息? 2019-08-06 10:59:24 +0800 CST
  • Martin Hope
    zdimension 鼠标指针在 Windows 中按下的箭头键上移动? 2019-08-04 06:39:57 +0800 CST
  • Martin Hope
    jonsca 我所有的 Firefox 附加组件突然被禁用了,我该如何重新启用它们? 2019-05-04 17:58:52 +0800 CST
  • Martin Hope
    MCK 是否可以使用文本创建二维码? 2019-04-02 06:32:14 +0800 CST
  • Martin Hope
    SoniEx2 更改 git init 默认分支名称 2019-04-01 06:16:56 +0800 CST

热门标签

windows-10 linux windows microsoft-excel networking ubuntu worksheet-function bash command-line hard-drive

Explore

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

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve