我应该在 git 别名脚本中使用 `sh -c \"...\"` 或 `"!f() {... ; }; f" 吗?

2024-02-05

我已经开始尝试编写带参数的 git 别名了。我见过一些人运行 shell 脚本

[alias]
  shAlias = !sh -c \" ... \"

和其他运行函数

[alias]
  fAlias = "!f() { ... ; }; f"

看起来(一旦我加快了 Bash 的速度——这还不是我现在的状态)我想要做的任何事情都可以用任何一种形式实现。

在什么情况下,其中一种优于另一种?

除了可行性之外,是否存在处理差异?内存使用/速度/等等?


TL;DR:对最简单的命令使用函数方法,一旦遇到任何引用问题,请切换到外部脚本。只是避免sh -c全部一起。


We can 看一下 git 源码 https://github.com/git/git/blob/217f2767cbcb562872437eed4dec62e00846d90c/run-command.c#L243。它解析出 a 中的引号git特定方式,如果结果没有 shell 元字符(包括空格),则作为文件执行,或者执行相当于execlp("sh", "-c", "result \"$@\"", "result \"$@\"", args...)否则。

基于此,创建别名的最佳方法肯定是创建外部脚本并使用:

[alias]
 myAlias = !/path/to/script

它需要一个外部文件,但在所有其他方面它都更好:

  • 您可以与任何您想要的翻译一起运行。你甚至可以跑步bash代码,因为你问,而其他形式只允许你运行sh代码(区别就像 C++ 与 C 一样)。
  • 除非您愿意,否则不会启动其他 shell。git will execve直接你的可执行文件。
  • 不需要转义。这只是一个普通的脚本。
  • 没有惊喜或git所需的知识。这只是一个脚本。

根据您的建议,亚军是:

[alias]
  fAlias = "!f() { ... ; }; f"

这不太好,因为:

  • 不幸的是你只能运行sh,因此不使用任何bash特征。
  • 总是会启动一个 shell,但至少它只是一个。
  • Some git报价需要特定的转义。
  • 你需要知道git的转义,但通常可以在不确切知道它如何执行命令的情况下完成,因为您只需使用函数的参数。

最后一个是迄今为止最糟糕的:

[alias]
  shAlias = !sh -c \" ... \"

这很糟糕,因为:

  • 你只能运行sh.
  • 它会无缘无故地启动一个额外的 shell。
  • 你需要both git逃脱以及额外的级别sh逃跑。
  • 您需要知道如何转义代码sh,如何双重转义git, 如何git追加"$@"如果有其他参数,则传递给您的命令,并将其他参数传递为$1, $2.

为了演示实际差异,假设您想为此命令创建一个别名,以通过以下方式获取远程服务器上的路径ssh:

ssh "$1" 'echo "$PATH"'

您可以将其逐字复制粘贴到文件中,添加 shebang,然后使用:

[alias]
  get-remote-path = !/path/to/my/script

或者你可以添加一点git转义并使用函数方法:

[alias]
  get-remote-path = "!f() { ssh \"$1\" 'echo \"$PATH\"'; }; f"

或者我们可以费力地逃脱并再次逃脱sh -c方法(不,没有最后一个词就不起作用):

[alias]
  get-remote-path = !sh -c 'ssh \"$1\" '\\''echo \"$PATH\"'\\' cthulhu

显然,最好使用脚本,或者最坏的情况下使用函数方法,直到您需要可以轻松引用的更复杂的命令。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我应该在 git 别名脚本中使用 `sh -c \"...\"` 或 `"!f() {... ; }; f" 吗? 的相关文章

  • 如何归档旧的 git 标签?

    我的 git 存储库中有一些不再重要的旧标签 我想存档标签 以便在运行 git tag 时默认情况下它们不会显示 我不想删除它们 因为我想保留历史记录 我怎样才能做到这一点 可以将标签保留在存储库中并避免将它们列为标签 它还可以避免默认克隆
  • 在 Ubuntu 上纯粹通过 bash 脚本安装 mysql 5.7

    我想要一个无需任何手动输入即可安装 MySQL 5 7 实例的 bash 脚本 我正在关注数字海洋教程 https www digitalocean com community tutorials how to install mysql
  • 将 stdout 作为命令行 util 的文件名传递?

    我正在使用一个命令行实用程序 该实用程序需要传递文件名以将输出写入 例如 foo o output txt 它唯一写入的东西stdout是一条消息 表明它运行成功 我希望能够通过管道传输写入的所有内容output txt到另一个命令行实用程
  • 如何忽略Git中以数字开头的文件?

    在某个文件夹中 我有名为foo jpg bar png等等 我想将它们保留在版本控制中 除了那些命名为1 baz png 2 zaz jpg等 因为它们实际上是生成的 我应该添加什么条目 gitignore 正则表达式如 0 9 似乎不起作
  • 具有非阻塞读取功能的 Bash 脚本

    我想使用命名管道将一些数据发送到根进程 这是脚本 效果很好 bin sh pipe tmp ntp if p pipe then mknod m 666 pipe p fi while true do if read line lt pip
  • Git:由于看似随机的合并,更改不断丢失

    我有一种感觉 这将是一个显而易见的答案 但我似乎无法解决 似乎发生的情况是 我向服务器提交 推送了一些更改 并且我的副本上的一切都显示正常 然后 另一位开发人员从同一分支的服务器中拉取 据我所知 据称看到了我的更改 进行一些修改 将它们提交
  • 错误:GitHub 目前无法显示这么大的文件 - 但该文件只有 1.06 MB [已关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我通过两种不同的方式将 HTML 文件上传到 GitHub 存储库 拖放以及使用终端上的 Git 添加 提交 推送 在这两种情况下
  • 列出其他人(即不是我)所做的提交?

    是否有一种标准方法可以列出 git 存储库中其他人 即不是我自己 所做的所有提交 I tried git log not author username 但看起来 not仅适用于修订版 的联机帮助页git log似乎没有提供反转谓词的方法
  • Git:检查文件是否存在于某个版本

    在我的应用程序中 我使用 git 对一些外部文件进行版本管理 我正在使用类似的命令git show HEAD 1 some file获取文件的某个版本 基于 git 标签 提交哈希或与 HEAD 的关系 当文件不存在时 会输出 致命 消息
  • 如何仅将整个嵌套目录中的头文件复制到另一个目录,在复制到新文件夹后保持相同的层次结构

    我有一个目录 其中有很多头文件 h 和其他 o 和 c 文件以及其他文件 这个目录里面有很多嵌套的目录 我只想将头文件复制到一个单独的目录 并在新目录中保留相同的结构 cp rf oldDirectory newDirectory将复制所有
  • 从 bash 脚本运行节点

    很简单 我正在尝试使用 cron 自动运行 nodejs 脚本 但是脚本本身似乎无法运行该文件 我的脚本很简单 usr bin env node node var node assets js update js 但是 在运行此命令时 它返
  • 如何在 git 中删除 subversion 远程?

    我有一个最初使用 git svn 创建的 git 存储库 现在我有一个推送到的 git 服务器 但 svn 存储库已丢失 我可以删除 svn 远程吗 如何 您可以编辑 git config文件并删除与要删除的遥控器关联的部分 您要删除的行可
  • 如何终止当前正在运行的git进程? [复制]

    这个问题在这里已经有答案了 git commit m 45 fatal Unable to create F SoftifyBD Projects proj 4 CMS Latest contentmanagementsystem git
  • 如何在 VS Code 中仅提交跟踪文件?

    git status 显示以下三个信息 要提交的变更 分阶段变更 未暂存提交的更改 未暂存更改 未跟踪的文件 我曾经git commit a 它提交 1 和 2 然而VS代码Commit All提交 1 2 和 3 Commit Stage
  • MP4 到 DASH(bash 脚本)

    我有一个网站 用户可以在其中上传视频文件 我想使用 DASH 流式传输所有内容以获得自适应比特率流式传输 因此 我编写了一个 bash 脚本 由 cron 运行 将所有 mp4 文件转换为 DASH 但它无法正常工作 出了什么问题 例如 使
  • git push origin 分支名总是推送到 master

    我搜索了一下 但似乎找不到答案 在我可以访问的两个盒子上 当我执行 git push dry run origin mytestbranch 时 我得到以下结果 To email protected cdn cgi l email prot
  • bash 自动完成:添加可能完成的描述

    是否可以使 bash 自动完成功能看起来像 Cisco IOS shell 中一样 我的意思是为每个完成添加简短的描述 如下所示 telnet 10 10 10 TAB Pressed 10 10 10 10 routerA 10 10 1
  • 如何列出 Git 1.7+ 中的所有远程分支?

    我试过了git branch r 但这仅列出我在本地跟踪的远程分支 如何找到我没有的列表 命令是否列出对我来说并不重要all远程分支或仅那些未跟踪的分支 For the vast majority 1 of visitors here th
  • 在powershell中检查文件是否可读且正常

    我是 powershell 新手 我想检查文件是否可读且正常 在 unix 中 我们可以使用 f 和 r 在一行中完成此操作 例如 以下 shell 脚本函数接受文件名作为参数并检查文件的可读性和规律性 与此等效的 powershell 是
  • 别名在 Bash 脚本中不起作用[重复]

    这个问题在这里已经有答案了 我有一个可执行文件command sh bin bash alias my command echo ok my command 我的终端是bash 当我像这样运行时 command sh 效果很好 当我像这样运

随机推荐

  • 使用 POST 请求重定向的好方法?

    我需要通过 POST 请求将用户重定向到外部站点 我想到的唯一选择是通过 JavaScript 提交表单 有任何想法吗 不太明白你的意思 所以我们举几个场景 用户应该将表单发布到您自己以外的服务器 很简单 只需将目标指定为表单操作即可
  • (Codesandbox,Vue)“属性或方法“children”未在实例上定义,但在渲染期间引用。”

    我目前正在构建一个状态管理器 它可以集成到多个前端框架中 包括 Vue 为了演示 Vue 中状态管理器的用法 我创建了一个简单的codesandbox 因为有一个实时代码示例总是很好 可以在自述文件中进行推广 但不知何故 我总是在代码和框中
  • Path 中加号的 Data 值是多少

    如何使用 Path 对象中的 data 属性绘制加号和减号 这是我的三角形路径对象 我需要将其更改为加号
  • JS 客户端 Exif 方向:旋转和镜像 JPEG 图像

    数码相机照片通常保存为带有 EXIF 方向 标签的 JPEG 为了正确显示 图像需要根据设置的方向进行旋转 镜像 但浏览器会忽略渲染图像的此信息 即使在大型商业 Web 应用程序中 对 EXIF 方向的支持也可能不稳定1 http www
  • Android:发送数据存储在MySQL中

    Solved 缺少 postData 的视图参数 已更改以反映这一点 我需要一些帮助 将 GPS 数据发送到服务器 该数据将使用 PHP 存储在 MySQL 数据库中 这是在我的 Java 文件中 ArrayList
  • JLabel setText 不更新文本

    我正在尝试使用以下方法更新 JLabelsetText 方法 但我无法重绘 JLabel 我必须使用repaint 方法来做到这一点 这是代码的一部分 我没有收到任何错误 但它没有更新 JLabel public void actionPe
  • 将 infoWindow 放置在远离标记的静态位置(Google 地图)

    我想要实现的 到目前为止找不到任何东西 是 infoWindow 没有附加到标记 我想将其放置在视口中的静态位置 并根据单击的标记交换内容 问 如何将谷歌地图标记信息窗口放置 而不仅仅是偏移 到固定位置 回答我自己的问题 如果有人需要这个
  • 如何禁用 #line 指令写入 T4 生成输出文件

    我在生成 T4 代码时遇到了一个小问题 我已将 T4 模板分解为单独的文件并将它们放置在不同的目录中 我已经这样做了 因此我的代码生成的部分内容可以在多个项目中重复使用 例如模型生成 存储库生成和服务生成都包含核心 EntityGenera
  • 双控制台输出?

    突然 当我在本地运行我的应用程序时 我得到了双控制台输出 有谁知道这可能是什么原因造成的 运行 Thin 和 Unicorn 时都存在该问题 gt Booting Thin gt Rails 4 0 0 application starti
  • 在 odoo 中安装 woocommerce 连接器

    我想连接 woocommerce 和 odoo 我在 Odoo 中安装 woocommmerce 连接器时遇到问题 我从那里得到了 woocommerce 连接器https github com OCA connector woocomme
  • 没有规则可以创建“opencv.exe”所需的目标“C:/opencv/build/lib/libopencv_world300d.dll.a”。停止

    所以我试图构建一个简单的 opencv 代码 但我不断收到此错误 而且我似乎在互联网上找不到任何解决方案 操作系统 Windows 8 1 编译器 GNU GCC 601 IDE CLion CMake 3 0 和 mingw64 这是我从
  • spring-mvc中将json解析为java对象

    我熟悉如何从我的返回 json Controller方法使用 ResponseBody注解 现在我正在尝试将一些 json 参数读入我的控制器 但到目前为止还没有运气 这是我的控制器的签名 RequestMapping value ajax
  • findOneAndUpdate 覆盖作为 doc 传递的 2 级以上深度对象中的属性

    假设我有这个架构 var UserSchema new Schema name firstName String lastName String 我创建这个用户 User create name firstName Bob lastName
  • 用户点击时使用ajax加载processing.js sketch

    我正在尝试通过单击 ajax 加载processing js 草图 但它不起作用 如果我立即加载草图 它会起作用 但不会在用户交互时加载 这是我的代码 clicker click function var canvasRef
  • 避免 Google Apps 脚本中出现 formatDate 错误

    我有一个函数可以存储在数组中并循环文档中的数据 在这个里面 有一些单元格的日期格式为 dd mm yyyy 但是当我通过电子邮件发送它时 看起来像2014 年 1 月 1 日星期三 00 00 00 GMT 0300 ART 我在这个函数内
  • IA-64 上出现段错误,但 IA-32 上没有

    我无法访问我的原始账户 https stackoverflow com users 211631 whacko cracko 如果可能的话 请版主合并帐户 这是我的问题 以下 C 程序在 IA 64 上出现段错误 但在 IA 32 上运行良
  • 使用 AngularJS 日期过滤器和 UTC 日期

    我有一个以毫秒为单位的 UTC 日期 我将其传递给 Angular 的日期过滤器以进行人工格式化 someDate date d MMMM yyyy 太棒了 除了someDate采用 UTC 时间 并且日期过滤器认为它是当地时间 我如何告诉
  • String(value) 与 value.toString() 有什么区别

    Javascript 在类型和类型转换方面有很多 技巧 所以我想知道这两种方法是否相同 或者是否存在某些特殊情况使它们不同 它们并不完全相同 实际上 作为函数调用的 String 构造函数 http bclary com 2004 11 0
  • Android:打开指定多个收件人的短信活动[重复]

    这个问题在这里已经有答案了 我正在尝试通过启动意图来启动手机短信提供商 我下面使用的代码是我用来启动意图的代码 Intent sendIntent new Intent Intent ACTION VIEW StringBuilder ur
  • 我应该在 git 别名脚本中使用 `sh -c \"...\"` 或 `"!f() {... ; }; f" 吗?

    我已经开始尝试编写带参数的 git 别名了 我见过一些人运行 shell 脚本 alias shAlias sh c 和其他运行函数 alias fAlias f f 看起来 一旦我加快了 Bash 的速度 这还不是我现在的状态 我想要做的