【问题标题】:Bash pwd and open with pipe not working [duplicate]Bash pwd 并打开管道不工作[重复]
【发布时间】:2015-06-28 23:37:31
【问题描述】:

我正在学习如何在 bash 中使用 I/O 重定向,并尝试了一些使用管道的示例,例如:

pwd | say
ls -l | grep "staff" > out.txt

但是当我尝试使用管道重定向同时使用pwdopen 时,命令失败,我只收到open 的使用情况。

我正在尝试的是:pwd | open

从 bash 打开当前目录的正确方法是什么?

【问题讨论】:

  • 那是什么open 命令?它是否读取标准输入?
  • open 从 shell from Apple documentation 打开文件。如何检查它是否接收到标准输入?
  • 如果你想为pwd打开Finder,你可以做pwd | xargs open
  • @khachik 谢谢,您应该将此作为答案发布,因为这对我有用。
  • 请注意,pwd | xargs open不可靠,因为如果当前目录路径嵌入了空格,它就会失败。

标签: macos bash unix terminal


【解决方案1】:

事后看来,有2个不同的答案


答:回答 OP 的问题按要求,以理解管道I/O 流

echo . | xargs open

# Equivalent solution, using the special "$PWD" shell variable.
printf '%s\0' "$PWD" | xargs -0 open

是将当前目录的路径传递给open CLI 通过管道 以便在 OSX 的文件系统浏览器 GUI 应用程序@987654328 中打开该目录的最可靠方法@。

请注意,pwd | xargs open 并不可靠,因为如果当前目录路径嵌入了空格,它就会失败 - 见下文。

  • open 要求输入通过命令行参数而不是通过stdin输入流提供,就像这里的情况一样(通过管道,|)。
  • 因此,为了将标准输入转换为参数,需要标准的 xargs 实用程序
  • xargs 接受标准输入 - 在这种情况下来自 管道 - 并调用指定为 参数的命令 (@987654335 @,在这种情况下)将标记化的标准输入作为该命令的参数
  • xargs 默认由 空格 分割
    • . 作为输入,不会发生拆分(或由shell 解释),因此可以将echoed 到xargs
    • 相比之下,特殊的$PWD shell 变量总是包含当前目录的完整路径,可能包含嵌入空格,所以额外需要采取一些步骤来确保将其作为单个参数传递给open
      • printf '%s\0' "$PWD" 打印当前目录的完整路径,以 NUL 字节 (0x0) 结尾。
      • 作为补充,xargs -0 将标准输入输入通过 NUL 拆分为标记 - 在这种情况下生成一个 单个 标记,保留单个输入行的值 - 包含 $PWD - as是。这是安全的,因为 NUL 不是文件名中的合法字节。
        • 注意:-0POSIX standard for xargs非标准扩展,但它在 BSD xargs(在 OSX 上使用)和 GNU xargs(在 Linux 上使用)都实现了)。保持 POSIX 兼容[1],下一个最好的方法是使用基于 line 的标记化和 -I 选项,如下所示:
          printf '%s' "$PWD" | xargs -I % open %

因此,实际上上述解决方案等价于xargs 最终执行的内容 - 参见下一节的解释):

open . 

# Equivalent solution.
open "$PWD"

[1] xarg-I 选项需要一个也符合 XSI 的 POSIX 系统。如果有人能用实际的术语向我解释这意味着什么,我将不胜感激。


B:提供最佳答案对所采用的技术没有限制

open .

open 需要 arguments 而不是 stdin 输入,而. 简洁且最有效地表示当前目录,导致open 在@987654361 中显示当前文件夹的内容@。

一个等效但更详细的解决方案是传递特殊的shell变量$PWD,它始终包含当前目录的完整路径(在引号中引用,以保护它免受shell expansions:

open "$PWD"

【讨论】:

    【解决方案2】:

    如果你想为pwd打开Finder,你可以做pwd | xargs open

    【讨论】:

    • 这将与嵌入空格的路径中断。如果涉及管道并且确实需要xargs,请使用pwd | xargs -I {} open {}。但是,正如@thatotherguy 在评论中对他自己的答案所指出的那样,更简单的是open "$(pwd)",或者更好的是open "$PWD",或者最好是open .
    • @mklement0 这不是解决一些现实生活问题的方法,OP 正在尝试理解管道,而 open . 是打开目录的最直接方式,它没有回答这个问题。
    • 同意。但是,pwd | xargs -I {} open {} 正在 回答问题稳健 - 与pwd | xargs open 不同。 (如果您需要最大的稳健性,请使用printf '%s\0' "$PWD" | xargs -0 open)。也就是说,一个好的答案的标志不仅是对直接要求的内容提供答案,而是指出更好的选择 - 但我认为现在我们的 cmets 已经涵盖了这一点。跨度>
    【解决方案3】:

    man open:

    -f  Reads input from standard input and opens the results in the
        default text editor.  End input by sending EOF character (type
        Control-D).  Also useful for piping output to open and having
        it open in the default text editor.
    

    同一手册,在“示例”下:

    ls | open -f 将“ls”命令的输出写入 /tmp 中的文件并在 默认文本编辑器(由 LaunchServices 确定)。

    因此你可以这样做pwd | open -f

    【讨论】:

    • 我尝试了您的解决方案,它在文本编辑器中打开了一个新文件,其中写入了当前目录。但我正在尝试让 Finder 打开当前目录。例如,如果我使用:open /Users/MyUser Finder 将打开目录(在 Finder 中)。
    • @romsearcher 这根本不涉及管道或重定向。您将使用 open . 或等效的 open "$(pwd)"
    • 是的,你是对的,管道不是必需的,但我试图了解管道的使用情况并想知道为什么管道在此设置下不起作用。
    • 参数和管道是分开的东西。您可以使用xargs 将管道数据转换为参数,使用echo 将参数转换为管道数据。
    猜你喜欢
    • 2015-10-30
    • 1970-01-01
    • 1970-01-01
    • 2012-03-26
    • 2017-07-13
    • 2015-01-22
    • 1970-01-01
    • 2016-05-13
    • 2021-09-08
    相关资源
    最近更新 更多