Bash 中的管道、标准输入和命令行参数

2023-12-23

考虑:

command1 | command2

command1 的输出是用作 command2 的标准输入还是用作 command2 的命令行参数?

例如,

cat test.sh | grep "hehe"

不使用管道的等效形式是什么?

I tried

grep "hehe" $(cat test.sh)

这似乎不正确。


grep "hehe" < test.sh

输入重定向 - 当然,仅适用于单个文件,而cat适用于任意数量的输入文件。


考虑符号:

grep "hehe" $(cat test.sh)
grep "hehe" `cat test.sh`

这些在这种情况下是等效的;使用 ' 更容易$(cmd)' 嵌套使用中的表示法,例如:

x=$(dirname $(dirname $(which gcc)))
x=`dirname \`dirname \\\`which gcc\\\`\``

(如果您想知道的话,这将为您提供安装 GCC 的基本目录。)

In the grep例如,发生的情况是test.sh被读取并分割成空格分隔的单词,并且每个这样的单词都作为参数提供grep。自从grep处理后面的单词"hehe" (where grep,当然,not请参阅双引号 - 在这种情况下不需要它们;作为一般规则,使用单引号而不是双引号,尤其是在复杂的字符串(如经常使用 shell 元字符的正则表达式)周围)...正如我所说,grep处理后面的单词"hehe"作为文件名,并尝试打开每个文件,通常会失败,因为文件不存在。这就是为什么该表示法在这种情况下不合适。


重新审视这个问题之后,还有更多可以说的——那些还没有说的。

首先,许多 Unix 命令被设计为“过滤器”;它们从某些文件中读取输入,以某种方式对其进行转换,然后将结果写入标准输出。此类命令设计用于在命令管道中使用。示例包括:

  • cat
  • grep
  • 特罗夫和亲戚
  • awk(有注意事项)
  • sed
  • sort

所有这些过滤器都具有相同的一般行为:它们采用命令行选项来控制其行为,然后读取指定为命令行参数的文件,或者如果没有此类参数,则读取标准输入。有些(比如sort)可以有选项来控制其输出而不是标准输出的位置,但这相对不常见。

有几个纯粹的过滤器——tr就是这样一种 - 严格读取标准输入并写入标准输出。

其他命令有不同的行为。 Eric Raymond 在“中提供了命令类型的分类法”UNIX 编程的艺术 http://www.catb.org/~esr/writings/taoup".

一些命令在标准输出上生成文件名列表 - 两个经典命令是ls and find.

有时,您希望将文件名生成器的输出应用为过滤器的命令行参数。有一个程序可以自动执行此操作 - 它是xargs.

通常,您会使用:

find . -name '*.[chyl]' | xargs grep -n magic_name /dev/null

这将生成带有扩展名 ' 的完整文件列表.c', '.h', '.y' and '.l'(C 源代码、头文件、Yacc 和 Lex 文件)。当列表被读取时xargs,它将创建命令行grep -n magic_name /dev/null在开头和每个单词(用空格分隔)作为参数。

过去,Unix 文件名不包含空格。在 Mac 和 Windows 的影响下,这样的空间现在已经司空见惯了。 GNU 版本find and xargs有解决这个问题的补充选项:

find . -name '*.[chyl]' -print0 | xargs -0 grep -n magic_name /dev/null

The '-print0' 选项表示“打印以 NUL '\0' 结尾的文件名”(因为不能出现在(简单)文件名中的唯一字符是 '/' 和 NUL,显然,'/' 可以出现在路径名中) 。相应的 '-0' tells xargs查找以 NUL 结尾的名称,而不是空格分隔的名称。

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

Bash 中的管道、标准输入和命令行参数 的相关文章

  • 如何并行执行4个shell脚本,我不能使用GNU并行?

    我有4个shell脚本dog sh bird sh cow sh和fox sh 每个文件使用 xargs 并行执行 4 个 wget 来派生一个单独的进程 现在我希望这些脚本本身能够并行执行 由于某些我不知道的可移植性原因 我无法使用 GN
  • 使用 shell=True 将 PATH 设置为 bitbake 的“source”在 Python 中没有效果

    下面是shell脚本中的代码 source proj common tools repo etc profile d repo sh repo project init branch repo project sync source pok
  • grep 排除文件的数组参数

    我想从我的文件中排除一些文件grep命令 为此我使用参数 exclude excluded file ext 为了更容易阅读 我想使用包含排除文件的 bash 数组 EXCLUDED FILES excluded file ext 然后将
  • Slurm:提交到多个节点时出错(“slurmstepd:错误:execve():python:没有这样的文件或目录”)

    我有一个 bash 脚本submit sh用于向 Slurm 服务器提交训练作业 其工作原理如下 正在做 bash submit sh p1 8 config file 将提交一些对应的任务config file至 8 个 GPU 分区p1
  • 运行具有外部依赖项的 Scala 脚本

    我在 Users joe scala lib 下有以下 jar commons codec 1 4 jar httpclient 4 1 1 jar httpcore 4 1 jar commons logging 1 1 1 jar ht
  • 比较两个文件的单列

    我有两个文件 每个文件都有两列 并用空格分隔 我想找到两个文件中第 2 列不相同的行 并将它们输出到第三个文件 file A 1 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 2 BBBBBBBBBBBBBBBBBBBBBB
  • bash 子 shell 中出现陷阱“kill 0”的分段错误

    我正在尝试编写一个并行构建多个 Dockerfile 的小脚本 但是如果我想取消该脚本 我也想杀死子进程 这样做的结果是segmentation fault 不知道为什么 为了澄清我正在杀死脚本 C trap kill 0 SIGINT S
  • Bash - 将键绑定到字符串(不是函数)

    如何获得键绑定以导致在命令行插入任意文本 在 zsh 中我这样做 bindkey s m myspecialscript 在 bash 中 有等效的吗 没有一个内置函数可以实现我想要的功能 bind e E home yourscript
  • 使用 SIGINT 默认处理程序时从 system() 返回值

    我遇到了一些奇怪的返回值system 当子进程从终端接收到 SIGINT 时 解释一下 从 Perl 脚本parent pl I used system 运行另一个 Perl 脚本作为子进程 但我还需要通过 shell 运行子进程 所以我使
  • linux下无法创建僵尸进程

    嗯 我有一个奇怪的问题 我无法在我的项目中创建僵尸进程 但我可以在其他文件中创建僵尸进程 有简单的说明 int main if fork 0 printf Some instructions n else sleep 10 wait 0 r
  • 在 byobu 选项卡中启动命令的脚本

    我已经使用 screen 来启动服务器进程 以便稍后我可以在需要时附加并再次分离以继续执行其他操作 它工作得很好 但我最近发现了 byobu 我真的很喜欢它 我想使用相同类型的脚本来运行服务器 但我想将其附加到 byobu 选项卡 而不是屏
  • 如何从shell脚本自动登录MySQL?

    我有一个 MySQL 服务器 其中有一个用户和密码 我想在 shell 脚本中执行一些 SQL 查询而不指定密码 如下所示 config sh MYSQL ROOT root MYSQL PASS password mysql sh sou
  • Bash for Windows 10 gcc 不会编译粘贴到根目录中的 c 文件

    正如标题所示 如果我将在其他地方编写的c文件粘贴到Linux子系统的根目录中 则无法编译它 我做了一个测试 我制作了两个不同标题的 hello world 程序 一个在 vi 中 我可以从 bash 界面进入 另一个在其他地方 当我编译了
  • bash 脚本抱怨文件名太长

    所以我有一个脚本可以执行此操作 jq 是命令行 JSON 处理器 echo Getting LB Node IDs echo LB STATUS jq loadBalancer nodes id 最后一行的输出是 1 2 3 但是当我尝试将
  • 为什么这个符号链接创建了两个实例

    我有一个用于我的点文件的安装脚本 我用来创建一个目录到我的主文件夹的符号链接 这些链接执行得很好 但创建了第二个符号链接 我无法解释为什么 项目中的文件夹结构如下所示 install sh scripts shell sh shell in
  • “/bin/bash -l”无效选项

    好吧 我正在尝试在我们的超级计算机上运行隐藏为一项作业的串行 MPI 作业 主要提交脚本基本上如下所示 bin bash l PBS l nodes 4 ppn 8 walltime 24 00 00 cat PBS NODEFILE un
  • Bash 实例未嵌套在 Dockerfile `RUN` 中

    嵌套 bash 实例会递增 SLVL 环境变量 http tldp org LDP abs html internalvariables html http tldp org LDP abs html internalvariables h
  • Bash 中的动态变量名称

    我对 bash 脚本感到困惑 我有以下代码 function grep search magic way to define magic variable 1 ls tail 1 echo magic variable 1 我希望能够创建一
  • Eclipse 的 Bash 脚本插件? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有正经的bashEclipse 的插件 我唯一的要求是语法突出显示 我用谷歌搜索过 但没有看到任何
  • 何时用引号将 shell 变量括起来?

    我应该或不应该在 shell 脚本中用引号括住变量吗 例如 下列说法正确的是 xdg open URL eq 2 or xdg open URL eq 2 如果是这样 为什么 一般规则 如果它可以为空或包含空格 或实际上任何空格 或特殊字符

随机推荐