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 / 问题 / 1460513
Accepted
WestCoastProjects
WestCoastProjects
Asked: 2019-07-17 08:37:22 +0800 CST2019-07-17 08:37:22 +0800 CST 2019-07-17 08:37:22 +0800 CST

在 bash 函数中使用“$@”与在 bash 中直接运行命令有不同的结果

  • 772

在命令行运行history时,结果是这样的:

$history aws s3 cp
16160  aws s3 cp s3://mybucket/air2008/10 .
16254  hists "aws s3 cp"

对于hists旨在成为上述内容的快捷方式的功能:

type hists
hists is a function
hists ()
{
    history 15000 | grep "$@"
}

运行时我们得到

09:40:44/csv $hists aws s3 cp
grep: s3: No such file or directory
grep: cp: No such file or directory

如果我们用引号运行它,那么它确实会得到正确的结果。但是引号是强制性的吗?

bash
  • 2 2 个回答
  • 32 Views

2 个回答

  • Voted
  1. Best Answer
    Daniel B
    2019-07-17T09:32:59+08:002019-07-17T09:32:59+08:00

    $hists "aws s3 cp"“扩展”到history 15000 | grep "aws s3 cp". 这意味着grep接收一个参数。

    $hists aws s3 cp扩展为history 15000 | grep "aws" "s3" "cp"。grep接收三个参数。

    第一个参数grep是模式。其他参数grep是要在其中查找模式的文件。当前文件夹中没有名为s3或cp的文件,因此grep显示错误消息。

    引号可以改变命令行中文本的含义。如果您希望参数包含空格,引号是实现此目的的一种方法。

    $hosts aws\ s3\ cp做同样的事情:通过在空格前添加反斜杠,shell 知道不使用通常的含义,即分隔参数。相反,它将变成一个字面的空白。

    与 . 的行为也没有区别"$@"。它的存在正是为了保留引用的参数。

    • 3
  2. Kamil Maciorowski
    2019-07-18T01:00:49+08:002019-07-18T01:00:49+08:00

    另一个答案很好。它解释了发生了什么:

    hists aws s3 cp扩展为history 15000 | grep "aws" "s3" "cp"。grep接收三个参数。

    第一个参数grep是模式。其他参数grep是要在其中查找模式的文件。当前文件夹中没有名为s3或cp的文件,因此grep显示错误消息。

    我的回答将允许您加固和修改该功能,以便hists aws s3 cp正常工作。


    原始代码中的第一个注释grep "$@"允许您向 注入选项,grep如下所示:

    hists -i LS
    

    您可能希望也可能不希望能够做到这一点。如果不是,那段代码应该是grep -- "$@". 但即便如此,您也可以将文件名传递给grep. 我希望您永远不会希望grep在函数中对文件进行操作。一些防止这种情况的机制会很有用。

    如果您希望能够注入选项,没有简单的方法可以阻止您将文件指定为附加参数。该函数应将多个参数传递给grep;它自己不知道哪个是选项,哪个是文件。有些逻辑可能会处理这个问题,但让我们保持简单。

    如果您可以在不向 注入选项的情况下生活grep,则可以确保该工具只获得一个参数,即模式。您可以使用grep -- "$1",但在这种情况下

    hists aws s3 cp
    

    将等同于hists aws,附加参数无关紧要。这不是你想要的,但它会阻止grep解析s3和cp/或抛出关于它们的错误。

    或者你可以使用grep -- "$*". 这就是POSIX 所说的"$*":

    当扩展发生在不执行字段拆分的上下文中时,初始字段应连接形成单个字段,每个参数的值由IFS变量的第一个字符分隔(如果IFS包含至少一个字符),或由<space> 如果IFS未设置,或者如果IFS设置为空字符串则没有分隔。

    双引号内是“不进行字段拆分的上下文”,标准IFS以 <space> 开头。这意味着如果您使用grep -- "$*", 命令

    hists aws s3 cp
    

    将触发grep -- "aws s3 cp",这正是您首先想要的。请注意,您将获得相同的结果

    hists aws  s3           cp
    

    尽管有多个空间。关键是hists根本看不到这些空间。它将aws,s3和cp作为单独的参数,然后"$*"使用单个空格连接三个字符串的机制。

    另一方面,这些命令:

    hists "aws s3 cp"
    hists "aws  s3           cp"
    

    将完全按照您的预期工作,无论您使用grep -- "$*"orgrep -- "$@"还是grep -- "$1". 当 ; 有更多参数时,这三个变体的行为不同hists;或更少(尝试hists不带任何参数)。

    因此,grep -- "$*"在某些情况下,您可以将引号设为可选。此变体还将阻止grep解析文件,无论您键入什么。

    • 1

相关问题

  • 在非 root 用户上用 bash 替换 zsh

  • 在 macOS High Sierra 的终端中设置环境变量时遇到问题

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

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

  • 如何从 WSL 打开 office 文件

Sidebar

Stats

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

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

    • 5 个回答
  • Marko Smith

    支持结束后如何激活 WindowsXP?

    • 6 个回答
  • Marko Smith

    远程桌面间歇性冻结

    • 7 个回答
  • Marko Smith

    Windows 10 服务称为 AarSvc_70f961。它是什么,我该如何禁用它?

    • 2 个回答
  • Marko Smith

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

    • 6 个回答
  • Marko Smith

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

    • 1 个回答
  • Marko Smith

    VirtualBox 无法以 VERR_NEM_VM_CREATE_FAILED 启动

    • 8 个回答
  • Marko Smith

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

    • 5 个回答
  • Marko Smith

    ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败:无法获取本地颁发者证书 (_ssl.c:1056)

    • 4 个回答
  • Marko Smith

    我如何知道 Windows 安装在哪个驱动器上?

    • 6 个回答
  • Martin Hope
    Albin 支持结束后如何激活 WindowsXP? 2019-11-18 03:50:17 +0800 CST
  • Martin Hope
    fixer1234 “HTTPS Everywhere”仍然相关吗? 2019-10-27 18:06:25 +0800 CST
  • Martin Hope
    Kagaratsch Windows 10 删除大量小文件的速度非常慢。有什么办法可以加快速度吗? 2019-09-23 06:05:43 +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
    Inter Sys Ctrl+C 和 Ctrl+V 是如何工作的? 2019-05-15 02:51:21 +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